nodejs puppeteer 爬虫 爬取滚动加载
爬取滚动加载页面数据
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({ width: 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库