技術戦略部より、tipsやノウハウなど技術的な話題を発信いたします。比較Node.jschromypuppeteerものすごく久しぶりにブログを書きます、開発チームのハッタです。Chromeにheadlessモードが追加されてから、Chromeを操作できるライブラリが色々出てきています。簡単なブラウザテストを例にとって比較してみようと思います。Chrome操作のパイオニアといった感じでしょうか。実行すると、Chromeが起動します。chromyとは別にChromeのインストールが必要です。DevToolsの開発チームが作っているとのことで、後発ながら本家と言えるでしょう。実行すると、chromiumが起動します。npmでpuppeteerをインストールするとchromiumも同時にインストールされるので、こちらのほうが環境構築の手間がかかりません。弊社コーポレートサイトのサイトマップページにあるURL全てに遷移し、スクリーンショットを撮るという処理を行ってみます。puppeteer両者とも普通にnpmで入れるだけですね。chromiumが起動と書きましたが、実際にどのようなプロセスが起動しているのか、インタラクティブモードでスクリプトを実行して確認してみましょう。...いくつかのChromeプロセスが"--headless"というオプション付きで出てきます。これらのプロセスを終了させるには、close()処理が必要です。Chromeプロセスは出てこない次はpuppeteerです。supported.」というエラーが出ます。一般ユーザで実行しましょう。※一般ユーザでも同様のエラーが出ることがあります。その場合は"--no-sandobox"オプションを付けるか、OSを変えましょう。17.10では出ませんでした。chromyはページを開いてからプロセスが作られましたが、puppeteerはpuppeteer.launch()の時点でchromiumのプロセスが確認できます。こちらも"--headless"オプション付きです。Chromeではなく、npmでインストールされたcromiumが起動しているのが分かります。/home/techblogger/node_modules/puppeteer/.local-chromium/...さらにページを開くためのpageオブジェクトを生成すると、末端のプロセスが1つ増えます。/home/techblogger/node_modules/puppeteer/.local-chromium/...なお、この後に実際にページを開いてもプロセスは変わりません。結果は変わらずプロセスを終了させるには、chromyと同じようにclose()を行います。chromiumプロセスは出てこない以上でプロセスの確認は終わりです。次は実際にブラウザテストを実行してみます。サイトマップページを開き、リンク先のURLを全て取得するとりあえず、サイトマップページ内のリンク先URLをコンソールに出力する処理を書いてみます。browser.close();})();両者はほとんど同じですね。evaluate()は、ブラウザ内で実行するスクリプトを渡し、結果を取得することができます。"ブラウザ内で実行するスクリプト"なので、Node.js側で定義した変数などは明示的に渡してあげないと参照できません。両者ともにREADMEやサンプルコードにはやり方が書いていなかったので、ソースコードを追ったりして調べました。需要の無い機能なのでしょうか。chromyは、evaluate()が内部で呼んでいる、_evaluateWithReplaces()というプライベートっぽい関数を直接実行します。この関数は、https://github.com/OnetapInc/chromy/blob/master/src/document.jsに書かれています。文字列を渡す場合は、下記のようにクォーテーションを含んだ文字列で渡さなければいけません。chromy.close();})();puppeteerはevaluate()に下記のように引数を追加することで実現できます。こちらのほうが簡単ですね。browser.close();})();変数だけでなく、関数を渡すやり方もあります。こちらは変数とは逆に、chromyに標準機能として実装されていて、puppeteerのほうがやや力技になります。chromyはdefineFunction()という関数があり、外部で定義した関数を渡すと、eveluate()の中で使えるようになります。関数を文字列で渡して、evaluate()の中でeval()で復元、という方法で実現できました。browser.close();})();以上が、evaluate()を使ってリンク先URLを取得する方法と、ちょっとした小技です。次は取得したURLにアクセスして、スクリーンショットを撮ってみます。取得したURLに1秒インターバルを置いてアクセスし、スクリーンショットを撮るブラウザテストを行う際、なるべく人間の動きに近いものにしたかったり、サーバーの負荷を考えたりすると、ある程度のインターバルを置いて動作するように書かなければいけません。ここではスクリーンショット保存だけでなく、JavaScriptを書き慣れていないとハマりやすいタイマー処理についても触れたいと思います。スクリーンショットを撮る部分はほぼ同じですが、puppeteerはファイル保存までやってくれるのでコード量が少し減ります。両者の一番の違いはやはりsleep()の有無でしょうか。他言語のsleepと同じように使える機能が標準で実装されていると便利ですね。自力で実装すると上記のようなコードになります。大したコード量ではないので、実装してしまうのもいいかもしれません。処理で、puppeteerのほうが2~3割処理時間が短いです。chromiumとChromeの違いでしょうか。スクリーンショットは、ファイルサイズの微妙な差はありますが、画質等に大きな違いは無いように見えます。書いて、複雑なスクレイピングなどをやりたいならこちらといった感じでしょうか。