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

posted @ 2021-07-26 17:40  mingruqi  阅读(633)  评论(0编辑  收藏  举报