1. 程式人生 > 實用技巧 >Puppeteer爬蟲實戰(三)(轉載)

Puppeteer爬蟲實戰(三)(轉載)

本篇文章針對大家熟知的技術站點作為目標進行技術實踐。

確定需求

  訪問目標網站並按照篩選條件(關鍵詞、日期、作者)進行檢索並獲取返回資料中的目標資料。進行技術拆分如下:

  1. 開啟目標網站
  2. 找到輸入框元素輸入關鍵詞,找到日期元素設定日期,找到搜尋按鈕觸發搜尋動作
  3. 解析搜尋返回的html元素構造目標資料
  4. 將目標資料儲存

編寫程式碼

'use strict';
const puppeteer = require('puppeteer');
const csv = require('fast-csv');
const fs = require('fs');

(async () => {
  const startUrl = 'https://www.infoq.cn/';
  const keyWord = 'CQRS';
  const browser = await puppeteer.launch({
    slowMo: 100, // 放慢速度
    headless: false, // 是否有頭
    defaultViewport: {// 介面設定
      width: 1820,
      height: 1080,
    },
    ignoreHTTPSErrors: false, // 忽略 https 報錯
    args: ['--start-maximized', '--no-sandbox', '--disable-setuid-sandbox'],
  });

  const page = await browser.newPage();
  await page.goto(startUrl).catch(error => console.log(error));
  await page.waitFor(1 * 1000);
  await page.click('.search,.iconfont');
  await page.type('.search-input', keyWord, { delay: 100 });
  const newPagePromise = new Promise(x => browser.once('targetcreated', target => x(target.page())));
  await page.click('.search,.iconfont');
  const targetPage = await newPagePromise;
  const dataCount = await targetPage.$eval('.search-body-main-tips span', el => el && el.innerHTML).catch(error => console.error(error));
  if (dataCount && dataCount > 0) {
    const dataEle = await targetPage.$$('.search-item');
    console.log(dataEle.length);
    const stream = fs.createWriteStream('infoq.csv');
    const csvStream = csv.format({ headers: true });
    csvStream.pipe(stream).on('end', process.exit);
    for (let index = 0; index < dataEle.length; index++) {
      const element = dataEle[index];
      const title = await element.$eval('a', el => el && el.innerHTML).catch(error => console.error(error))
      const desc = await element.$eval('.desc', el => el && el.innerHTML).catch(error => console.error(error))
      csvStream.write({
        標題: title || '',
        摘要: desc || '',
      });
    }
    csvStream.end(() => { console.log('寫入完畢'); });
  }
  await targetPage.screenshot({ path: 'infoq.png' });
  await browser.close();
})();

具體的如下

視訊

總結

  上面的例子還是比較簡單的,站點本身是資訊站(其實有搜尋介面根本不需要解析html