爬取滚动加载页面数据
nodejs+puppeteer
之前有写一篇爬取普通网站的数据
nodejs爬虫 爬取爱奇艺 node + cheerio 爬取滚动加载页面
地址
https://blog.csdn.net/qq_43017024/article/details/118786153
但是遇到有反爬策略的网站,查不到页面dom数据的来源接口怎么办呢?
此时我们可以用到 puppeteer
Puppeteer本质上是一个chrome浏览器,只不过可以通过代码进行各种操控。比如模拟鼠标点击、键盘输入等操作,有点像按键精灵,网页很难分清这是人类用户还是爬虫,所以限制也就无处谈起。通过一招简单的模拟用户操作就能破解绝大部分限制,它就是由谷歌出品的爬取动态网页神器Puppeteer。
比如优酷的,犹豫对爬虫的不熟悉,我以为数据就在这几个接口里面,花了一天的时间去找结果什么也没找到,后来发现原来是优酷的反爬策略
直接上代码
const puppeteer = require('puppeteer') //设置网址 var url = 'https://www.youku.com/' async function start(bool) { //启动浏览器,传入headless为false可以打开窗口 const browers = await puppeteer.launch({ headless: bool }) //启动新页面 const page = await browers.newPage() //设置页面打开时的页面宽度高度 await page.setViewport({ 1920, height: 1080, }) //链接网址 await page.goto(url) var content, $ await page.evaluate(function () { var top = 0 //每200毫秒滚动100px var timer = setInterval(() => { console.log(window.scrollY); window.scrollTo(0, top += 100) }, 200); //15秒后清除定时器并开始获取内容 setTimeout(() => { clearInterval(timer) var box = $('.module_mod') let List = [] for (let i = 0; i < box.length; i++) { let e = box.eq(i) let title let obj = { title: '', name: [] } if (e.find('.module_main_title').length > 0 && e.find('.pack_title').length > 0) { title = e.find('.module_main_title').eq(0).text() obj.title = title let textlist = e.find('.pack_title') for (let idx = 0; idx < textlist.length; idx++) { obj.name.push(textlist.eq(idx).text()) } List.push(obj) } if (e.find('.tabs_main_title').length > 0 && e.find('.pack_title').length > 0) { title = e.find('.tabs_main_title').eq(0).text() obj.title = title let textlist = e.find('.pack_title') for (let idx = 0; idx < textlist.length; idx++) { obj.name.push(textlist.eq(idx).text()) } List.push(obj) } } console.log(List); List = JSON.stringify(List, undefined, 4) //以下是下载json,创建元素 var ele = document.createElement('a'); //设置下载文件名 ele.download = "youku.json"; //隐藏元素 ele.style.display = "none"; //字符内容转变成blob地址 var blob = new Blob([List], {type: 'text/json'}); //如果是链接,这里也可以直接设置链接地址 ele.href = URL.createObjectURL(blob); document.body.appendChild(ele); //模拟点击 ele.click(); //移除元素 document.body.removeChild(ele); }, 15000); }) } start(false)
需要注意的是这里的滚动加载我用的是计时器的加载方式,滚动的速度和时间都可以自行更改
对于获取页面的一些操作都在setTimeout,这样可以在自动打开的浏览器的控制台里可以console出来
setTimeout外面的代码会在cmd窗口打印出来,但是因为我的知识盲区太广,我不知道怎么把在setTimeout里面拿到的数据传到外面,还请多多指教
任何网站都要有一个分析一下dom布局,找到你想要获取数据的模块,检查是否都一样之后再去获取dom
————————————————
版权声明:本文为CSDN博主「Tee_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43017024/article/details/118787817