Chrome 조작 라이브러리 'Puppeteer'로 스크래핑 해 보았습니다.

10632 단어 ChromepuppeteerNode.js

소개



Headless Chrome을 Node.js에서 작동하는 라이브러리에 Puppeteer가 있습니다 (게다가 Google에서 만든!).
이것이 스크래핑 툴로서도 사용할 수 있을 것 같기 때문에, 시험에 Wikipedia에서 타이틀, 본문, 이미지를 취해 보았습니다.

설치 절차



OS : Windows10
Puppeteer 버전 : 1.5.0

설치는 다음 명령을 치는 것입니다.

Puppeteer 설치
$ npm install puppeteer

※사전에 Node.js와 npm을 인스톨 할 필요가 있습니다.

소스 코드(전체)



crawler.js
const puppeteer = require('puppeteer');

(async () => {
  // const browser = await puppeteer.launch();
  const browser = await puppeteer.launch({ headless: false }); // ヘッドレスにしない


  const page = await browser.newPage();

  const url = 'https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%87%E3%83%AA%E3%83%BC%E3%83%9A%E3%83%B3%E3%82%AE%E3%83%B3';
  await page.goto(url, { waitUntil: 'domcontentloaded' }); // domを読み込むまで待機

  // タブを移動
  const pages = await browser.pages();
  const detailPage = pages[1];
  await detailPage.bringToFront();

  // タイトル取得
  let selector = '#firstHeading';
  const titleDom = await detailPage.$(selector);
  if (titleDom) {
    title = await detailPage.$eval(selector, e => e.textContent);
    console.log(title);
  }

  // 本文取得
  selector = '#mw-content-text > div > p';
  const contentDom = await detailPage.$$(selector);
  if (contentDom.length > 0) {
    content = await detailPage.$$eval(selector, elements => {
      let datas = [];
      for (e of elements) {
        datas.push(e.textContent);
      }
      return datas;
    });
    for (c of content) {
      console.log(content);
    }
  }

  // 画像取得
  selector = '#mw-content-text > div > table.infobox.bordered > tbody > tr:nth-child(2) > td > a > img';
  const dom = await page.$(selector);
  if (dom) {
    await dom.screenshot({ path: 'penguin.png' });
  }

  await browser.close();
})();

소스 코드(상세)



기억해 두는 편이 좋은 것만 메모.

로드할 때까지 대기



page.goto()로 페이지 전환할 때 waitUntil에서 페이지 로드를 기다립니다.
  • domcontentloaded 로 설정하면 HTML을로드 할 때까지 대기합니다.
  • load 다음 이미지를로드 할 때까지 기다립니다
  • networkidle0 500 밀리 초 연결이 없을 때까지 대기

  • 자바스크립트를 불러올 때까지 기다리려고 하면 networkidle0networkidle2 라는 것도 있는 모양.

    로드할 때까지 대기
    await page.goto(url, { waitUntil: 'load' });
    

    탭 이동



    링크를 클릭하면 새 탭으로 이동할 수 있습니다.
    그 경우는 그 탭으로 이동할 필요가 있습니다(이번의 소스에서는 필요 없지만・・・).

    탭 이동
    const pages = await browser.pages();
    const detailPage = pages[1];
    await detailPage.bringToFront();
    

    스크래핑



    텍스트나 속성을 취득할 때는, 기본이 쓰는 방법이라고 생각합니다.
    이 예라고 textContent를 지정하고 있으므로 요소내의 텍스트를 취득합니다.

    스크래핑
    title = await detailPage.$eval(selector, e => e.textContent);
    

    이미지 얻기



    DOM에 대해서도 스크린 샷을 얻을 수 있습니다. 물론 페이지에도 걸릴 수 있습니다.

    이미지 얻기
    await dom.screenshot({ path: 'penguin.png' });
    

    실행



    시작
    $ node crawler.js
    



    어쩐지, 이미지가 잘 잡히지 않았습니다・・・.
    이런 경우에는 이미지의 URL에 액세스한 다음 page.screenshot()을 하면 좋을 것 같습니다.

    결론



    비교적 간단하고 편리했습니다.
    Puppeteer는 API의 종류가 꽤 많기 때문에, 여러가지 시험해 보는 것도 재미있을 것 같습니다만, 공식의 API 문서를 불러도 잘 모르는 곳도 아직 있군요・・・.

    좋은 웹페이지 즐겨찾기