Chrome

Puppeteerメモ

Puppeteer
GoogleChrome/puppeteer

Headless Chrome Node API

based on Headless Chrome

Kikobeats/browserless

High level automation API for working with Headless Chrome

Headless Chrome Crawler

モダンフロントエンドに対応したヘッドレスChromeによる分散クローラー

Puppeteerの使いどころ

  • Chromeで動けば良い

  • E2Eテスト用途ではない

  • 自動操作が目的である(スクレイピング、キャプチャ)

コード内では ブラウザの UI 操作 を Puppeteer API に実行させ、 DOM の読み取りや加工は page.evaluate() に流す。 Puppeteer には cheerio のような API はない。 Chromium 実行環境で innerHTML / outerHTML を読み取って cheerio に渡すことはできる。

tips

ERR_CERT_COMMON_NAME_INVALID

UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: SSL Certificate error: ERR_CERT_COMMON_NAME_INVALID

const browser = await puppeteer.launch({
  headless: false,
  ignoreHTTPSErrors: true
});

use proxy server with authentication

const puppeteer = require('puppeteer');

(async() => {
  const proxyUrl = 'http://proxy.example.com:8000';
  const username = 'bob';
  const password = 'password123';

  const browser = await puppeteer.launch({
    args: [`--proxy-server=${proxyUrl}`],
    headless: false,
  });

  const page = await browser.newPage();

  await page.authenticate({ username, password });
  await page.goto('https://www.example.com');

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

wait / sleep

// wait for selector
await page.waitFor('.foo');
// wait for 1 second
await page.waitFor(1000);
// wait for predicate
await page.waitFor(() => !!document.querySelector('.foo'));

要素のテキスト取得

const text = await page.$eval('.selector', element => element.textContent);

要素の HTML 取得

const html = await page.$eval('.main-container', e => e.outerHTML);

名前を指定してフレームを取得

const frame = page.frames().find(frame => frame.name() === 'myframe');

ファイルをダウンロードして保存

ブラウザのダウンロード機能を経由して保存したファイルを得る方法。 Page.setDownloadBehavior がダウンロードバーに相当し、ダウンロードフォルダを指定することができる。 この際、指定するパスは path.resolve() を使って適切な文字列を downloadPath に割り当てるとよい。

ブラウザのUI操作でダウンロードバーに落ちてくるケースであれば上記で対応できるが、 クリックしただけではページが開いてしまうようなケースでは他の様々なアプローチが存在する。

POSTリクエストを送る

$ curl http://www.google.com -d 'a=b&c=d'
await page.setRequestInterceptionEnabled(true);
page.on('request', request => {
  const overrides = {};
  if (request.url === 'http://www.google.com') {
    overrides.method = 'POST';
    overrides.headers = {
      'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
    };
    overrides.postData = 'a=b&c=d';
  }
  request.continue(overrides);
});
await page.goto('http://www.google.com');

page.exposeFunction

ブラウザの window オブジェクトに Node.js 関数を渡して実行させることができる。 サンプルでは crypto モジュールを require してブラウザから md5 ハッシュを生成している。 もう1つのサンプルでは fs モジュールを require して window.readfile 関数を実現している。

Run on

Heroku

AWS Lambda