[puppeteer] ヘッドレスブラウザの操作でスクレイピング、クローリング

[puppeteer] ヘッドレスブラウザの操作でスクレイピング、クローリング

puppeteer とは

puppeteer とは、GUIを操作することなく、プログラムからAPIでブラウザ(Chrome)を制御できる Node.js で作られた ライブラリ です。ヘッドレス(GUIなし)でも制御できるので高速です。

Node.jsのライブラリとして提供され、npm からインストールすることで puppeteer から操作することになる最新の Chromium がインストールされるので、環境構築も簡単です。

内部では Chromium が動くことになるので、Javascript も実行してくれます。つまり、SPAなどスクリプトで動的にコンテンツが生成されるようなページでも問題なく操作することができます。

ブラウザを使って手動で行えるほとんどのことが実行可能なため、E2Eテストやスクレイピングなどに幅広く利用できます。

環境構築

OS

Node.jsが動けば、Windows でも Linux でも動作するはずです。WindowsとMac環境で動作を確認しました。ただし後述の通り、Windows環境ではヘッドレス状態でタイムアウトする現象が発生することがあります。

Node.js

puppeteer は Node.js のライブラリなので、Node.js をインストールする必要があります。

puppeteer は、Node v6.4.0 以降のバージョンで動作します。ただし、puppeteer は操作結果を Promise で返すため、async/await が使えた方が便利です。なので、Node v7.6.0 以降のバージョンを用意したほうがよいです。

puppeteer

Node.js がインストールできると、npm が利用できるようになるので、puppeteer をインストールします。適当なプロジェクトディレクトリで次のコマンドを実行します。

$ npm install puppeteer --save

Puppeteerをインストールすると、APIで動作することが保証されているChromiumの最新バージョン(~170Mb Mac, ~282Mb Linux, ~280Mb Win) がダウンロードされます。そこそこのサイズです。

環境自体は、puppeteer のインストールのみで完了です。

サンプルコード

環境構築が済めば、さっそく動かしてみます。上記ページにある使い方のページを引用します。

example.js

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({ path: 'example.png' });

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

やっていることは、https://example.com にアクセスして、取得したページのスクリーンショットを撮って保存するというものです。ヘッドレスなので実際のブラウザは画面では表示されません。

やっていることは、[ブラウザを立ち上げ -> ページ作成 -> 指定URLに遷移 -> スクリーンショット -> ブラウザ終了] です。

単純明快でわかりやすいですね。

puppeteer でなにができるのか

上記ページは、puppeteer が提供するAPIのドキュメントです。さまざまな手動操作に対応するAPIが確認できます。

以下、グーグルで検索して、puppeteer の Github ページにアクセスするサンプルです。

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();

  // Googleにアクセス
  await page.goto('https://www.google.co.jp/');
  // 検索窓に「puppeteer github」と入力
  await page.type('#lst-ib', 'puppeteer github');
  // 検索ボタンクリック
  await page.focus('input[name="btnK"]');
  await page.click('input[name="btnK"]');
  // 遷移完了を待機
  await page.waitForNavigation();
  // 検索結果の先頭リンクをクリック
  await page.click('.rc > .r > a');
  // ページタイトルを表示
  const title = await page.title();
  console.log(title);

  // スクリーンショット
  await page.screenshot({ path: './ss.png' });

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

puppeteer.launch 関数のオプションで、ヘッドレスモードで起動するかどうかを指定できます。headless: false で実行すると、実際にブラウザが操作されている様子が確認できます。

Windows だと、ヘッドレスモードので実行すると、かなり時間がかかってしまいます。場合によってはタイムアウトすることもあります。原因は不明です。むしろGUIが表示されている方が処理が早かったりします。Macだとこんなことはありませんでした。

以上です。

Javascriptカテゴリの最新記事