• Puppeteer爬取单页面网站的数据示例


    场景

    • 昨天试了一下爬取根据网页查询参数的不同而变化的页面,今天来试试爬取单页面应用,url不发生变化,只是页面内的按钮点击导致数据的重新请求。

    主要实现思路

    • 利用Puppeteer可以模拟用户点击操作,等待接口返回等各种优秀的API,可以保证在数据结束后完成页面数据提取。

    代码实现,以开源众包的页面为例

    • 开源众包这个页面挺适合用来做示例,因为通过下一页的按钮去调用ajax请求,当到达最后一页时,下一页按钮会自动有一个disabled属性,我们就可以根据这个disabled属性来判断是否还有下一页。
    const common = async (workFunc) => {
      const startTime = +new Date();
      console.log(`进入方法`);
      const browser = await puppeteer.launch();
      const page = await browser.newPage();
      typeof workFunc === 'function' && await workFunc(page);
      await page.close();
      await browser.close();
      console.log('方法结束,耗费时长:', +new Date() - startTime);
    };
    const crawler = async (url, selectors) => {
      const list = [];
      await common(async (page) => {
        await page.goto(url);
        async function runOnce() {
          const result = await page.evaluate((selectors) => {
            const res = [];
            selectors.forEach(selector => {
              const { key, value, field } = selector;
              const domList = document.querySelectorAll(value);
              Array.prototype.slice.apply(domList).forEach((dom, index) => {
                const newVal = dom[field] || dom.innerText;
                res[index] = res[index] || {};
                res[index][key] = newVal;
              })
            })
            return res;
          }, selectors);
          list.push(...result);
          const disabled = await page.$eval('.btn-next', el => el.disabled);
          console.log('一页数据已获取,当前下一页按钮状态:', result[0], disabled);
          if (!disabled) {
            // 触发按钮点击,使用page.click就是不能触发按钮的点击,只能用这个骚操作
            await page.$eval('.btn-next', el => el.click());
            // 等待接口完成
            await page.waitForResponse(response => {
              return response.url().includes('contractor-browse-project-and-reward') && response.status() === 200;
            })
            await runOnce();
          }
        }
        await runOnce();
      })
      return list;
    }
    
    // 使用
    const url = 'https://zb.oschina.net/projects/list.html';
    const selectors = [
      {
        key: 'title',
        value: '.el-row .title',
        field: 'innerText'
      },
      {
        key: 'tags',
        value: '.el-row .tags',
        field: 'innerText'
      },
      {
        key: 'money',
        value: '.el-row .money',
        field: 'innerText'
      },
      {
        key: 'skills',
        value: '.el-row .skills',
        field: 'innerText'
      },
      {
        key: 'bidding',
        value: '.el-row .bidding',
        field: 'innerText'
      },
      {
        key: 'pubtime',
        value: '.el-row .pubtime',
        field: 'innerText'
      }
    ];
    
    crawler(url, selectors).then(result => {
      console.log(result);
      fs.writeFile('项目.json', JSON.stringify(result), 'utf-8', err => {
        if(err) {
          console.log(err);
          return;
        }
      });
    })
    

    结果展示

    -

    小结

    • 不得不承认,Puppeteer对于爬取这种以前很难爬取的单页面应用来说,确实提供了不少便利。
  • 相关阅读:
    帮助中心 7D-我的私家设计师 设计师品牌服饰集成网 7D服装定制!
    libiconv的静态编译
    “好饭不怕晚” 怎么理解这句话?_百度知道
    “好饭不怕晚” 怎么理解这句话?_百度知道
    隆庆祥_百度百科
    【图】高级西服定制、量身定制(英国/意大利进口面料商务着装、结婚礼服、高档衬衫)
    量身定制顺美男女西服、衬衫、大衣、T恤等
    高级西服定制
    关于我们-成功人士西装定制服务第一品牌派斯特PAISTETAILOR绅士礼服
    断舍离:日式概念的流行-财经网
  • 原文地址:https://www.cnblogs.com/aloneMing/p/13476744.html
Copyright © 2020-2023  润新知