Chromeのヘッドレスブラウザがやってくる。というわけで試してみた。

注意：この記事は古いです。2016年06月06日に書いた記事です。

2017/04/14 追記：
Chrome59から正式にヘッドレスモードが搭載されます。
ヘッドレスモードではPhantomJSなどのようにJavaScriptでヘッドレスブラウザを制御することも可能です。
https://chromium.googlesource.com/chromium/src/+/master/headless/

2017/06/07 追記：
NightmareJS風に操作できるライブラリをリリースしています。
ヘッドレスChromeをもっとも簡単に操作できると思われるNightmareJS風ライブラリ
http://qiita.com/devneko/items/3689b46fc2bcdb8121a8

-----------------------------------------------------

先日、Googleの人が「Headless Chrome is coming so soon」とつぶやきました。
https://twitter.com/samccone/status/739166801427210240

ヘッドレスブラウザというのはGUIのないブラウザです。GUIはありませんが内部的にはページのロードから描画までを行います。余計な機能がなく効率的に動作し、APIやコマンドラインなどから操作できることから、フロントエンドのテストなどで活躍します。

代表的なヘッドレスブラウザはPhantomJSです。自分はちょうどPhantomJSを使ったツールを開発していて([yes-we-canvas](http://qiita.com/devneko/items/8225baad9ebb7a512f8a))、PhantomJSの標準への対応がいまいちなことなどから、blinkエンジン(Chromeのエンジン)のヘッドレスブラウザがあればいいのにと思っていたところでした。

そこにこのツイートを見つけましたので、勢い余って最新masterをビルドして試してみました。

## ビルド環境

- Ubuntu Linux
- 8GB以上のメモリを積んだマシン(メモリが少ないとlinkでエラーになる)
- できればCPU性能が高いマシン

Linuxでビルドする場合はUbuntu以外のディストリビューションはサポートしていないようです。
CentOSなどで進めると下記のようなエラーが出て進めなくなります。

```
ERROR: Only Ubuntu 12.04 (precise), 14.04 (trusty),  14.10 (utopic), 15.04 (vivid), 15.10 (wily) and 16.04 (xenial)  are currently supported
```

ビルドにかなり時間がかかります。(安いVPSだと3~5時間くらいかかります)
クラウドなどで一時的に高性能なマシンを借りた方がいいです。

## 前準備(Chromeのサンドボックスツールを用意します)

headlessブラウザの実行に必要となりますので、先にインストールしておきます。

下記のURLからDownloadしてunzipします。
https://download-chromium.appspot.com/?platform=Linux_x64&type=snapshots

```
cd chrome-linux
sudo cp chrome_sandbox /usr/local/sbin/chrome-devel-sandbox
sudo chown root:root /usr/local/sbin/chrome-devel-sandbox
sudo chmod 4755 /usr/local/sbin/chrome-devel-sandbox

# .bashrcなどに設定しておくとよい
export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome-devel-sandbox
```

## ビルド手順

1. ビルド用のツール群depot_toolsをインストールします
    下記のページを参考に git clone してPATHを通します。
    https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up

    ```bash
    git clone  https://chromium.googlesource.com/chromium/tools/depot_tools.git
    export PATH=$PATH:/path/to/depot_tools
    ```

    以降のステップで現れるコマンド fetch, gn, ninja はdepot_toolsに含まれます。

2. Chromiumのソースをダウンロードします。

    ```bash
    mkdir chromium
    cd chromium
    fetch --no-history chromium
    ```

3. ビルドに必要なファイルをインストールします

    ```bash
    cd src
    ./build/install-build-deps.sh
    ```

4. ビルドします

    ```bash
    cd headless
    mkdir -p out/Release
    echo 'import("//build/args/headless.gn")' > out/Release/args.gn
    echo 'is_debug = false' >> out/Release/args.gn
    echo 'is_component_build = true' >> out/Release/args.gn
    gn gen out/Release
    ninja -C out/Release headless_shell
    ```

## 実行
1. 実行します

    ```bash
    ./out/Release/headless_shell --remote-debugging-port=9222 --remote-debugging-address=0.0.0.0 https://youtube.com
    ```
remote-debuggingのオプションがない場合は、内部でレンダリングまで完了するとアプリケーションは終了するようです。  

2. ブラウザでインスペクタを開きます

http://your-host-address:9222/

開くと見ているページの名前が出てくるのでクリックするとインスペクタが起動します。


## 試してみて

現在はPhantomJSのように簡単にヘッドレスブラウザを制御する方法は用意されていません。
公式資料によるとheadless_shellはそもそもphantomjsに相当するようなものではなく、
ヘッドレスブラウザを実現するライブラリ(headless library)を使ったサンプルアプリケーションに過ぎないようです。
じゃあheadless libraryを使えばいいじゃんという話なのですが、現在はC++向けのAPIしかなく、APIの資料もほとんど見当たりません。
公式発表される頃にはドキュメントは整備されるかもしれませんが、基本的にC++からでないと制御できないようなので、C++にあまり馴染みのない人には気軽に扱えるものではないと思います。

というわけで、ChromeのヘッドレスブラウザをPhantomJSの代替として期待してはいけません。
しかし、これをベースにしてどんどん使いやすいツールが開発されると思います。
そう遠くないうちにPhantomJSの代替になるような製品が現れるか、もしくはPhantomJSがChrome のHeadless Libraryを採用するかもしれません。

## その他

ユーザーエージェントこんな感じでした。
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome Safari/537.36"

headless_shellに --screenshot オプションを指定するとスクリーンショットが撮れるようです。

## 参考

- [Get the Code: Checkout, Build, & Run Chromium](https://www.chromium.org/developers/how-tos/get-the-code)
- [GET DEPOT TOOLS
](https://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html#_setting_up)
- [Headless Chromium README.md](https://chromium.googlesource.com/chromium/src/+/master/headless/)
- [Headless Chrome architecture](
https://docs.google.com/document/d/11zIkKkLBocofGgoTeeyibB2TZ_k7nR78v7kNelCatUE/edit?pref=2&pli=1#heading=h.pjk3jj497v8p)