Skip to content

Instantly share code, notes, and snippets.

@isnot
Created June 16, 2017 20:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isnot/360fdb57b57e94230d668882df5052a7 to your computer and use it in GitHub Desktop.
Save isnot/360fdb57b57e94230d668882df5052a7 to your computer and use it in GitHub Desktop.
ブラウザのオートメーションへの道(2017年6月版)

ブラウザのオートメーションへの道(2017年6月版)

自分なりにいろいろ調べた結果をまとめます。 ただし、これは現時点での状況からわかったことで、賞味期限は比較的短いだろうと思います。

はじめに

ウェブ・ブラウザを、プログラムから操って、自動処理をしたいと思いました。 プログラムはjavascriptで書きます。 ある程度の複雑な手順の処理が想定され、特にスクリーンショットの取得が重要と考えています。

実ブラウザを使ったE2Eテストという技術があり、そのやり方が非常に参考になりますが、やりたいことの内容は結構違ってきます。

前提

Ubuntuを使います。

Dockerを使って実行環境をコンテナ化します。

ChromeもしくはChromiumを、Headlessモードで使うのが良さそう。

普段使っているデスクトップ環境と同じPCで動かしますが、普段の環境と干渉したくありません

調査

Headless Chrome

Webアプリケーション実行環境向けのDockerコンテナの中に、Chrome v59 をインストールしてみました。 ワンライナーのコマンドラインから、任意のURIのサイトのスクショを撮ることができました。

次にリモートからDevTool経由で操縦してみました。 しかし、WebGL対応が不十分のようで、特定のWebサイトでは途中で処理が止まってプロセス毎おちてしまいました。 これに対する解決策としては、以下が考えられます。

  • 依存するライブラリを個別に調査、インストールする
  • Xvfbを使って、デスクトップ環境を整備する

前者は手間が煩雑です。またバージョンが進むと無駄になる可能性があります。 後者は、結局それってHeadlessはどこ行ったの?という疑問が湧きます。結局インストールするものが多く、重くなるってことです。 コンテナのディスク・イメージを小さく保ちたいので、重要な観点です。

Xvfbを使ってHeadlessを実現するのは古来からある由緒正しき方法なのですが、物理画面を使わないという事を除いては、普通にデスクトップ環境を別途構築することと等価なので、今の私の望むものとは離れてしまいます。

もっとも先に挙げた問題は、Chromeの開発が進んで成熟すれば、近いうちに改善することが期待できます。

なお、これとは別に以下のことも模索したのですが、挫折しています。

  • VNCを使って、コンテナ内のブラウザをリモートから操作する
    • デスクトップ環境が必要
  • SSHのX転送を使って、同じくコンテナ内のブラウザをリモートから操作する
    • コンテナにはXの環境がなく、従って必要なライブラリが足りず、実現できなかった
    • xauthがない!

Selenium

ブラウザの自動操縦に関するパイオニア的存在。 だがしかし、そもそもSelenium自体がデカイのであまり触りたくない。

  • Selenium + 普通のブラウザ(Chrome、Firefox、Edge)
    • 自動操縦できますが、デスクトップ環境でブラウザの画面を開いて、それを操縦するイメージです
    • 普段遣いのデスクトップでそういうのは邪魔になります
  • Selenium + Xvfb + 普通のブラウザ
    • 上記と似ていますが、普段のデスクトップ環境の代わりに、仮想の(物理的には存在しない)デスクトップを使います
    • 使い勝手は求めるものに近づきますが、環境構築が結局はデスクトップ環境を構築するそれに近く、なんとなく重い
  • Selenium + Xvfb + Headless Chrome
  • Selenium + Headless Chrome
    • これはまだ調べてない。たぶんまだお手軽な方法が確立されていないかも

PhantomJS

もう少し「ブラウザのオートメーション」の原点に立ち返ったとき、PhantomJSは非常に注目に値します。 十分な機能を備え、エコシステムは結構充実しています。

参考:Ingress Ice - PhantomJSを使って、インテルマップのスクショを連続的に自動で取得するアプリ

しかし次のような点が気になります。

  • 開発が停滞している
  • 黒幕であるQtWebkitがそもそも捨てられた存在なので、仕方がない
  • 生のPhantomJS向けスクリプトは、書くのがツラい
  • 実は「PhantomJSはNodeスクリプトではない」ので、Node.jsのエコシステムはそのままでは使えない(ラッパーはある)

CasperJS

CasperJSは、PhantomJSのラッパーで、書きやすいです。 先月はこれを使ってプロトタイプを作成していましたが、使い勝手が良く、欲しかった機能が備わっており、まずまずの印象です。 PhantomJSの負の面は引きずっています。

Nightmare.js

CasperJSと同じく、元々PhantomJSのラッパーでした(v1)。書きやすいようです。 v2になって、Electronベースに移行しました。 Electronは、Node.js+Chromiumという、現在進行系で最先端のテクノロジーを使っているため、PhantomJSよりもさらにデスクトップの実ブラウザに近いです。 しかし、Electronはいまのところ、デスクトップ環境が必要です。(そもそもデスクトップ向けのアプリを作るためのものなので) Headless対応が進行中のようです。

Chromy

Node.jsの環境の中から、Headless Chromeを操縦するライブラリです。 Nightmare.jsと同じように書けることを目指しているようです。 ぱっと見ですが、必要な機能は揃っているようでした。 ただし、新顔なだけあって、実績に不安があります。参考例がなかったり、ドキュメントが整備されていなかったりするようです。

まとめ

これ以外にも、プラウザ・テストを実行するためのイロイロや、Headless Chromeを操縦するためのアレコレについてもざっくり調べましたが、期待が持てなさそうだったり、学習コストが大きそうで手付かずだったりします。

そのうえで、まとめ。

今すぐ始める場合は、CasperJSかChromyが良いように思います。 過去の実績や参考例の充実であれば、CasperJSになります。 将来性を取ってChromyを選択しつつ、ElectronのHeadless対応を待って、後々Nightmare.jsに移行するということも、悪くないと思います。

以上でした。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment