マストドンで盛り上がる最中、
こっそり一部で盛り上がってたChromeのヘッドレスモード
MacOSXで少し試してみたいと思います。
開発中の機能ということで、仕様の変更もあると思いますが、2017/4/16段階ではちゃんと以下のやり方で動作してます:)
準備
Google Chrome Canaryをインストール
開発段階にある機能がのってるchromeです。ささっと入れちゃいます。
nodejsインストール(v6.3以上)
ちなみに今回試したのはv7.9.0
シェルにCanaryバイナリへのエイリアスを作成します(僕は.zshrcに追加しました/bashの人は.bash_profileかな)
alias chrome-c='/Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary'
設定を読み込みます(source ~/.zshrc)
適当なディレクトリを作成して、その中にscript.jsを作成します。
$mkdir headless-test
$npm install chrome-remote-interface
$vim script.js
const CDP = require('chrome-remote-interface');
CDP((client) => {
// Extract used DevTools domains.
const {Page, Runtime} = client;
// Enable events on domains we are interested in.
Promise.all([
Page.enable()
]).then(() => {
return Page.navigate({url: 'https://example.com'});
});
// Evaluate outerHTML after page has loaded.
Page.loadEventFired(() => {
Runtime.evaluate({expression: 'document.body.outerHTML'}).then((result) => {
console.log(result.result.value);
client.close();
});
});
}).on('error', (err) => {
console.error('Cannot connect to browser:', err);
});
// [引用](https://github.com/cyrus-and/chrome-remote-interface)
実行してみる
ターミナルを2画面開いて
一つで先に
$ chrome-c --headless --remote-debugging-port=9222 https://chromium.org
特に出力はなく、入力待ちみたいな状態になります
もしmesa library周りのエラーが出たら--disable-gpuオプションをつけると良いそうです。
もう一つで
$node script.js
スクリプト内のhttps://example.comをアクセスしたいurlに変更してください
以下はqiita.comへアクセスした際の出力
https://qiita.com/
https://cdn.qiita.com/assets/public-f33264c77b8d85793c9875b153a1a98b.min.css
https://cdn.qiita.com/assets/siteid-large-c5f1d2812cc28cb0621d57061b9eb0f5.png
https://www.google.com/recaptcha/api.js
https://b.hatena.ne.jp/images/entry-button/button-only.gif
https://b.hatena.ne.jp/js/bookmark_button.js
...
読み込みされてるようです!
以上!!
おまけ
Nginxで確認したアクセスログ
自サイトへリクエストを送ってログをチェックしてみました
[16/Apr/2017:14:30:04 +0900] "GET / HTTP/1.1" 200 2783 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/60.0.3072.0 Safari/537.36" "-"
HeadlessChromeってなってます!
ページロードの計測
script.jsを以下のように変更してみました。
const CDP = require('chrome-remote-interface');
CDP((client) => {
// extract domains
const {Network, Page} = client;
// setup handlers
Network.requestWillBeSent((params) => {
console.log(params.request.url);
});
Page.loadEventFired(() => {
client.close();
console.timeEnd('loadtimer')
console.log('timer-end')
});
// enable events then start!
Promise.all([
Network.enable(),
Page.enable()
]).then(() => {
console.log('timer-start')
console.time('loadtimer')
var res = Page.navigate({url: 'https://qiita.com'});
return res;
}).catch((err) => {
console.error(err);
client.close();
});
}).on('error', (err) => {
// cannot connect to the remote endpoint
console.error(err);
});
実行した結果
// 実行結果
timer-start
https://qiita.com/
https://cdn.qiita.com/assets/public-f33264c77b8d85793c9875b153a1a98b.min.css
https://cdn.qiita.com/assets/siteid-large-c5f1d2812cc28cb0621d57061b9eb0f5.png
https://www.google.com/recaptcha/api.js
https://b.hatena.ne.jp/images/entry-button/button-only.gif
https://b.hatena.ne.jp/js/bookmark_button.js
https://platform.twitter.com/widgets.js
...
loadtimer: 1260.686ms
timer-end
qiitaトップは、1sくらいでページ読み込みができるみたいです(これでちゃんと計測できてるのかな?)
参考
https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md
https://github.com/cyrus-and/chrome-remote-interface