Headless Chrome(ヘッドレス Chrome)がついに、Chrome 59に搭載されました。
GUIのないLinux環境でも簡単にChromeが実行できるようになりました。
これでリリース後にデザイン崩れをチェックしたり、毎日のサイトチェックなんかにも利用できます。
試しに、Yahoo! JAPANのトップのニュース確認という体で毎時にスクショを撮ってみます。
Google ChromeをUbuntuにインストール
今回はUbuntuの環境だったのでapt-get
を使います。
###apt-get
でChromeをインストールできるようにする
$ echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee -a /etc/apt/sources.list
deb http://dl.google.com/linux/chrome/deb/ stable main
$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
OK
$ sudo apt-get update
apt-get
でgoogle-chrome-stableをインストールする
$ sudo apt-get install google-chrome-stable
$ google-chrome-stable --version
Google Chrome 61.0.3163.100
無事に最新版が入りました。
スクリーンショットを撮る
google-chrome --headless --screenshot
コマンドでヘッドレス Chromeのスクリーンショットを撮ることができます。
GPUのない環境なので --disable-gpu
を付け、 --window-size
で横x高さを指定することができます。
$ google-chrome --headless --disable-gpu --screenshot --window-size=1000,800 https://www.yahoo.co.jp/
[1001/180757.875913:INFO:headless_shell.cc(468)] Written to file screenshot.png.
screenshot.png を確認してみるとこんな感じ
良い感じですが、文字化け・・・
Headless Chromeの日本語化
日本語フォントが入っておらず文字化けしてしまっていたため、フリーで使えるIPAフォントをインストールします。
(他にも色々使えるみたい、お好みで! https://wiki.ubuntulinux.jp/UbuntuTips/Desktop/InstallFont)
$ sudo apt-get install fonts-ipafont fonts-ipaexfont
$ fc-list
/usr/share/fonts/truetype/dejavu/DejaVuSerif-Bold.ttf: DejaVu Serif:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf: DejaVu Sans Mono:style=Book
/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Italic.ttf: Liberation Sans Narrow:style=Italic
/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf: DejaVu Sans:style=Book
/usr/share/fonts/opentype/ipafont-mincho/ipam.ttf: IPAMincho,IPA明朝:style=Regular
/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf: Liberation Sans:style=Regular
/usr/share/fonts/truetype/liberation/LiberationMono-BoldItalic.ttf: Liberation Mono:style=Bold Italic
/usr/share/fonts/truetype/liberation/LiberationSerif-Italic.ttf: Liberation Serif:style=Italic
/usr/share/fonts/truetype/liberation/LiberationMono-Bold.ttf: Liberation Mono:style=Bold
/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Regular.ttf: Liberation Sans Narrow:style=Regular
/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf: DejaVu Sans:style=Bold
/usr/share/fonts/truetype/liberation/LiberationSerif-Bold.ttf: Liberation Serif:style=Bold
/usr/share/fonts/opentype/ipaexfont-gothic/ipaexg.ttf: IPAexGothic,IPAexゴシック:style=Regular
/usr/share/fonts/truetype/liberation/LiberationMono-Regular.ttf: Liberation Mono:style=Regular
/usr/share/fonts/opentype/ipafont-gothic/ipagp.ttf: IPAPGothic,IPA Pゴシック:style=Regular
/usr/share/fonts/truetype/liberation/LiberationSans-Italic.ttf: Liberation Sans:style=Italic
/usr/share/fonts/truetype/liberation/LiberationSerif-BoldItalic.ttf: Liberation Serif:style=Bold Italic
/usr/share/fonts/truetype/liberation/LiberationSansNarrow-BoldItalic.ttf: Liberation Sans Narrow:style=Bold Italic
/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf: DejaVu Sans Mono:style=Bold
/usr/share/fonts/opentype/ipaexfont-mincho/ipaexm.ttf: IPAexMincho,IPAex明朝:style=Regular
/usr/share/fonts/opentype/ipafont-mincho/ipamp.ttf: IPAPMincho,IPA P明朝:style=Regular
/usr/share/fonts/opentype/ipafont-gothic/ipag.ttf: IPAGothic,IPAゴシック:style=Regular
/usr/share/fonts/truetype/fonts-japanese-mincho.ttf: IPAexMincho,IPAex明朝:style=Regular
/usr/share/fonts/truetype/fonts-japanese-gothic.ttf: IPAexGothic,IPAexゴシック:style=Regular
/usr/share/fonts/truetype/liberation/LiberationMono-Italic.ttf: Liberation Mono:style=Italic
/usr/share/fonts/truetype/liberation/LiberationSans-BoldItalic.ttf: Liberation Sans:style=Bold Italic
/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf: Liberation Serif:style=Regular
/usr/share/fonts/truetype/liberation/LiberationSansNarrow-Bold.ttf: Liberation Sans Narrow:style=Bold
/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf: Liberation Sans:style=Bold
/usr/share/fonts/truetype/dejavu/DejaVuSerif.ttf: DejaVu Serif:style=Book
再度確認
$ google-chrome --headless --disable-gpu --screenshot --window-size=1000,800 https://www.yahoo.co.jp/
Slackへスクショを送る
curlからSlack APIでスクショを送ってみます。
files.upload
へ先程のscreenshot.png
をアップロードします。
今回の例ではtest
チャンネルへ送っています。
$ curl -F file=@screenshot.png -F channels=test -F token=xoxb-xxxxx-xxxxxx https://slack.com/api/files.upload
ページ全体を確認したい場合
高さ800pxに指定しているため、途中で表示が切られてしまいます。
ある程度高さ決まっているページであれば固定でもよいですが、そうもいかないサイトも多いハズ。。。
window.document.body.offsetHeight
なんかを取得してプログラム書いて動的に指定することもできるっぽいですが、ちょっとめんどう、、、(Puppeteer)
PDFは扱いにくいですが、PDFでもっと簡単に書き出しすることもできます。
--print-to-pdf
を付けるだけ
$ google-chrome --disable-gpu --print-to-pdf https://www.yahoo.co.jp/
$ ls output.pdf
output.pdf
output.pdf
というファイル名で保存されました。
スマホページのデザインを確認したい
そのままだとHeadless Chrome 固有のUser Agentでリクエストがされるため、普通はPCページしか読み込めません。
対象のサイトがUAでページを出し分けしている場合 --user-agent
でUAを指定することでスマホページを表示させることができあます。
google-chrome --headless --disable-gpu --screenshot --window-size=375,800 --user-agent="Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1" https://www.yahoo.co.jp/
Jenkinsのjobに登録し定期実行させる
あとはJenkinsのjobにshellscriptとして登録し、定期実行を指定するだけです。
--screenshot
の後にファイル名を指定することができるので、実行日時を入れて、
--dump-dom
でHTMLをログに表示させ、後から確認したときにもわかりやすくします。
また、 --hide-scrollbars
のオプションでスクロールバーを非表示にして隠すことができます。
SCREENSHOT=`date +%Y%m%d_%H%M%S-pc.png`
google-chrome --headless --disable-gpu --dump-dom --hide-scrollbars --screenshot=$SCREENSHOT --window-size=1280,800
https://www.yahoo.co.jp/
curl -F file=@$SCREENSHOT -F channels=test -F token=xoxb-xxxxx-xxxxxx https://slack.com/api/files.upload
ビルドトリガーで定期的に実行
H * * * *
これで毎時スクリーンショットを撮ってSlackに送るようになりました。
おわり
複雑なSVGの表示とかCSSとか、PhantomJSではレンダリングが微妙なものも試してみたのですが、
やってみた感じまんまChromeで表示した時のスクリーンショットが作れました。当たり前ですが
ただ、helpがなかったり、ドキュメントが発見できなかったりで、 --user-agent
や --hide-scrollbars
のオプションを最終的にchromiumのソースコードから探し出しました。まだまだ情報が少ない・・・
最初Serverlessでやろうと思ったんですが、Chromeのサイズが大きくてLambdaにアップロードできない・・・
とりあえずJenkinsのサーバーに入れてみました、Jenkinsのリリースジョブと組み合わせて、サーバーに上がったらスクショ撮って、画像認識させて変更箇所送らせるってフローを作ればCIが捗りそうです。