docker コンテナ + capybara-webkit でウェブサイトのスクリーンショットを撮影する


準備

Dockerfile 作成。

$ vi Dockerfile

内容はこんな感じ。

FROM ruby
RUN apt-get update && apt-get install -y libqt4-dev libqtwebkit-dev xvfb fonts-ipafont fonts-ipafont-gothic fonts-ipafont-mincho
RUN gem install capybara-webkit --no-ri --no-rdoc
ADD fonts.conf /etc/fonts/fonts.conf
ADD /capture.rb /capture.rb
ADD /capture.sh /capture.sh
RUN chmod +x /capture.sh
ENTRYPOINT ["/capture.sh"]

libqt4-dev と libqtwebkit-dev はヘッドレスブラウザを立ち上げるために必要なやつ。
xvfb はヘッドレスな X Window System サーバーを立ち上げるために必要なやつ。
ipafont, fonts-ipafont-gothic, fonts-ipafont-mincho はヘッドレスブラウザ上で日本語を含むサイトを正しく表示するために必要なやつ。
という感じっぽい。

次に、コンテナ内で実行させるスクリプトを作成する。
自作の Web サービス用に書いた処理からコピペしたもので、オプションとかは適当。

$ vi capture.rb
require "capybara-webkit"

if ARGV.size < 2
  abort "Usage ruby capture.rb URL OUTPUT_PATH"
end

url, output_path = ARGV[0], ARGV[1]
driver = Capybara::Webkit::Driver.new('web_capture')
browser = driver.browser
browser.visit(url)
browser.window_resize(browser.get_window_handle, 500, 500)
browser.render(output_path, 500, 500)

ruby capture.rb URL OUTPUT_PATH のように実行すると URL を見にいってスクショを OUTPUT_PATH に保存するようにしている。

ラッパーのシェルスクリプトも作成しておく。今回も docker で xvfb-run しようとしたときに Xvfb failed to start というエラーが出てしまう現象の解決方法 - Qiita のワークアラウンドを入れた。
(実行するコマンドが長いのでこうしてるけど、ださいのでもっといい感じにしたかった…。)

$ vi capture.sh
#!/bin/sh
rm /tmp/.X99-lock || echo 'Lock not found, continuing normal setup' && xvfb-run ruby /capture.rb $@

あと、フォントにアンチエイリアスを効かせるために fonts.conf を用意する必要があるんだけど、長いので prgrphs/fonts.conf at f91624e3ea2c02eb3c85e5c1763f5d85ab23ebe2 · tily/prgrphs を参照してください。

$ vi fonts.conf

デフォルトの fonts.conf を編集して、<fontconfig> タグの直下に下記の設定を追加してる感じです。

<match target="font">
    <edit name="antialias" mode="assign">
        <bool>true</bool>
    </edit>
</match>

実行

まずはイメージをビルド。

$ docker build -t capture .

実行。

docker run -v $(pwd):/data/ -ti capture http://ja.wikipedia.org/ /data/test.png
rm: cannot remove '/tmp/.X99-lock': No such file or directory
Lock not found, continuing normal setup
[DEPRECATION] Capybara::Webkit::Driver#browser is deprecated.
WARNING: The next major version of capybara-webkit will require at least version 5.0 of Qt. You're using version 4.8.6.
Request to unknown URL: http://ja.wikipedia.org/
(略)

(略) の部分に capybara-webkit のワーニングが出まくるけど、スクショ自体はうまく撮影できた。

$ ls -l test.png 
-rw-r--r-- 1 root root 1319199  2月  9 02:36 test.png
$ file test.png 
test.png: PNG image data, 821 x 6364, 8-bit/color RGBA, non-interlaced

クラウド上のサーバーで作業していたので、Web サーバーを立ち上げて確認する。

$ python -m SimpleHTTPServer 3000
Serving HTTP on 0.0.0.0 port 3000 ...

http://www.example.com:3000/test.png で画像を表示して確認した。
縦長になってしまったのでだいぶトリムしたけどこんな感じのスクショがとれる。

まとめ

docker コンテナ + capybara-webkit でウェブサイトのスクリーンショットを撮影することができた。フォントがまだいまいちな気がするので、他のフォントを入れてためしてみたいなー。