2018年6月2日、PhantomJSのリポジトリがついにアーカイブ化されました。PhantomJSのメインメンテナーは、
PhantomJSは、TwitterやNetflixでも単体テストやパフォーマンステストで使用されていた、ヘッドレスブラウザのデファクトスタンダードでした。ヘッドレスブラウザとは、GUI
これまでPhantomJSを使ってきた人たちは、徐々にヘッドレスChromeに切り替え始めています。一方で、
そこで本特集では、ヘッドレスChromeと、それを扱うためにChromeデベロッパーツールのチームが開発した、Puppeteerの実践的な解説を交えながら、これらの疑問に答えたいと思います。
本特集の構成
第1章では、ヘッドレスChromeとPuppeteerを紹介しながら、PhantomJSやSeleniumといった、これまでのツールとの共通点や違いについて解説します。第2章では、実際のコーディングにあたって必要となる、最新のJavaScriptやPuppeteerのAPIについて解説を進めます。第3章および第4章では、E2E
なお本特集には、多数の書籍や雑誌記事を執筆されている大竹智也さんに、レビュアーとして参加していただきました。たいへん貴重なご意見をいただき、心から感謝しています。
サンプルコードでPuppeteerを体験
Puppeteerは、ヘッドレスChromeの操作に特化したNode.
Puppeteerを使うことで、ヘッドレスChromeの提供する機能が、JavaScriptのプログラムから簡単に操作できるようになりました。これによって、テストの自動化はもちろんのこと、クローリング、スクレイピング、サービス監視およびWebページのPDF化など、さまざまな用途に使用できます。
実行環境
最新のPuppeteer
- Node.
js:10. 15. 0 - Puppeteer:1.
11. 0
なお、Puppeteerのサンプルコードでも使用されているasync/
最新の構文が使用できない環境では、Puppeteerのコードはすぐに複雑化してしまう傾向にあります。そのため、Node.
セットアップ
手もとの環境にNode.
スクリーンショットの撮影
それでは、実際にPuppeteerのサンプルコードを動かしてみましょう。この時点ではまだ、Puppeteerがどのようなツールかは理解していなくても問題ありません。まずは、先ほど作成したディレクトリ内に、
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: 'screenshot.png'});
await browser.close();
})();
次に、下記のコマンドでサンプルコードを実行してみましょう。
この10行に満たないコードを実行するだけで、ヘッドレスChromeを立ち上げ、指定したURLのスクリーンショットを撮影し、プロセスを適切に終了させることができました
なお、最新のJavaScriptを使ってコーディングした経験がなければ、サンプルコード内の見慣れない構文に戸惑ってしまうかもしれません。これらの新しい構文のうち、const宣言やアロー関数は比較的簡単に理解できます。
しかし、非同期処理を便利に扱うためのasync/
ヘッドレスブラウザが求められる背景
通常のブラウザ
ヘッドレスブラウザを選択する最大のメリットは、その安定性とパフォーマンスです。GUI
ヘッドレスブラウザが必要とされる理由の一つとして、AngularJS、React、Vue.
しかし、これらのSPAでは、実際にブラウザ上でJavaScriptを実行しなければ、最終的にどのようなHTMLがレンダリングされるのかを知ることが難しくなってきました。したがって、このようなサイトにE2Eテストやクローリング、スクレイピングを行うためには、ブラウザによる操作を自動化する必要性が出てきました。
継続的インテグレーションの普及
特に最近では、Jenkins、Travis CI、CircleCIなどの継続的インテグレーション、すなわちCI
サーバ上でE2Eテストを実行するためには、GUIは必要ありません。そのため、安定して高速に動作するヘッドレスブラウザに対する期待が高まってきました。
ヘッドレスChromeの特徴
ヘッドレスブラウザへの期待の高まりを受け、数年前から噂されていたヘッドレスモードがChrome59から搭載され、利用可能になりました。
これまで本特集では、一貫して
PhantomJSとの違い
PhantomJSとヘッドレスChromeは、どちらもヘッドレスで実行される点でとてもよく似ています。大きな違いとして、PhantomJSがレンダリングエンジンに古いWebKitを使用しているのに対して、ヘッドレスChromeは最新のBlinkを採用していることです
PhantomJS | ヘッドレスChrome | |
---|---|---|
開発状況 | 終了 | 活発 |
レンダリングエンジン | 古いWebKit | 最新のBlink |
パフォーマンス | △ | ◯ |
標準仕様への対応 | △ | ◯ |
ヘッド |
× | ◯ |
複数タブ対応 | × | ◯ |
ヘッドレスChromeに切り替えることで、高いパフォーマンスの恩恵を受け、さらに世界で半数のシェアを持つChromeと高い互換性を維持できます。ただし、どうしてもWebKitを使い続けたい場合は、開発の終了したPhantomJSか、ヘッドレスブラウザではありませんが、SafariのようなWebKitベースのブラウザを自動化する必要があります。
パフォーマンス
Hacker Noonの記事で、ヘッドレスChromeとPhantomJSのパフォーマンスを比較した結果が紹介されています。検証方法は、それぞれのヘッドレスブラウザを用いて、Ruby on Railsのデフォルトページに1,000回アクセスするだけの単純なものです。
ベンチマークの結果、ヘッドレス ChromeはPhantomJSと比較して、45%の時間のうちに、62%のメモリ消費量で動作するという結果を残し、高いパフォーマンスが発揮できることを証明しました。
標準仕様への対応
ヘッドレスChromeを採用する大きなメリットの一つとして、最新のJavaScriptの構文やAPIが利用できることが挙げられます。
Chromeは標準仕様への対応が早く、const宣言やアロー関数およびasync/
ヘッド「フル」モード
開発する際に見過ごせない機能が、ヘッド
ヘッドレスモードでしか実行できないPhantomJSでは、デバッグのためにログをたくさん仕込んだり、スクリーンショットを何度も撮影する場面がよく見られます。一方Chromeでは、ヘッドレスモードを解除することで、いつもと同じように画面上で何が起きているかを把握できるので、デバッグに役立てることができます。
基本機能の違い
そのほかにも、いくつか仕様面で大きな違いは見られます。
たとえば、PhantomJSではタブの概念がないため常に
また、PhantomJSには実装されている、別ページに遷移させないためのナビゲーションロック機能が、ヘッドレスChromeではサポートされていない
しかし、このようなPuppeteerの機能不足は、今後少しずつ解消されていくと考えられます。
Puppeteerの魅力
ヘッドレスChromeを操る方法は大きく分けて2つあります
WebDriverを間に挟むことで、同じインタフェースに対応しているさまざまなブラウザを、同一のスクリプトで同じように操作できます。一方、ブラウザごとに異なるAPIを使って直接操作すると、ほかのブラウザとの互換性が失われる代わりに、そのブラウザ固有の機能を利用できます。
Seleniumは幅広いブラウザをサポートするために、多くの機能を犠牲にしています。一方、PuppeteerはヘッドレスChromeに特化することで、Seleniumにはないさまざまな機能をサポートしています。実際のところ、どちらか一方が常に優れているということはなく、目的に応じた使い分けが必要です。
しかし、PuppeteerにはSeleniumにはない魅力が数多く存在します。そこで、それらの魅力を一つずつ紹介していきます。
大きなコミュニティ
Puppeteerは、Chromeデベロッパーツールの開発チームによってメンテナンスされています。開発チームのGoogleブランドによる安心感もたしかに無視できませんが、それ以上に大きなオープンソースコミュニティによって支えられています。
GitHub上でも、Seleniumの3倍以上となる4万件を超えるStarが付けられており
簡単なセットアップ
Seleniumを使ってヘッドレスChromeを扱うためには、Seleniumだけでなく、WebDriverをインストールし、対応するChromeのバージョンをそろえるなどの準備が必要です。それに対してPuppeteerは、Puppeteerさえインストールすれば、最新のChromium
ChromeおよびChromiumは、いずれもヘッドレスモードで起動できます。しかし、最新のバージョンを使用でき、さらにブラウザ自動化に必要のない機能が削ぎ落とされたChromiumのほうが、より多くの場合で最適な選択になるでしょう。
なお、どちらを使っても解説内容は大きく変わらないため、本特集ではChromiumも含めてChromeと表記しています。
充実したデバッグ
ヘッドレスChromeの機能としてヘッド
しかし、スローモーションで再生することや、デバッガを仕込んで開発者ツールを開くことが可能になっており、Puppeteerにはデバッグのための機能が充実しています。なお、デバッグの具体的な手順については、第2章で取り上げます。
豊富な機能
Puppeteerには実用的な機能が豊富に取りそろえられています。これらの機能の中には、リクエストやレスポンスを書き換えたり遮断できるものがあり、外部サービスのモックを用意するなどに役立ちます。
また、パフォーマンスやカバレッジの計測といった、利用者にとって便利な機能が常に追加され続けています。これらのユニークな機能については、第3章以降で取り上げていきます。
信頼性の高いコード
Puppeteerを使用することで、SPAに対しても信頼性の高いコードを書くことができます。
Seleniumを含むほとんどのライブラリでは、アンカーリンクのクリックやHistory APIの呼び出しは、画面遷移として扱われません。そのため、画面遷移が確認できるまでsetTimeout()
を実行するといった、冗長なコードを挿入しなければならない場面がよく見られます。このようなコードは、可読性が低いだけでなく、コードの実行結果も不安定になってしまいがちです。
しかし、PuppeteerはURLが切り替わるすべてのイベントを画面遷移と定義しているため、SPA専用の特別なコードを必要とせず、シームレスに動作させることができます。
まとめ
第1章では、ヘッドレスブラウザが求められる背景から、ヘッドレスChromeの特徴とPuppeteerが持つ魅力を順に紹介しました。本章を通じて、コーディングに向けての期待も高まったのではないかと思います。そこで次章からは実際の利用方法を解説していきます。