zoukankan      html  css  js  c++  java
  • 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({
         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

  • 相关阅读:
    react中refs的使用
    在npm发布自己造的轮子
    如何阅读一本书——分析阅读模板
    如何阅读一本书——检视阅读模板
    Redis教程——检视阅读
    如何阅读一本书——分析阅读Pre
    SVN常用功能介绍(二)
    SVN常用功能介绍(一)
    分页sql大全
    .NetCore 登录(密码盐+随机数)
  • 原文地址:https://www.cnblogs.com/Im-Victor/p/15062603.html
Copyright © 2011-2022 走看看