RでWebページのスクリーンショットを撮るにはheadless Chromeが今風?
従来、RでWebページのスクリーンショットを撮るにはwebshotパッケージが活躍してきました。しかし、webshotパッケージの内部で動くPhantomJSは開発が停止して久しいです。
そんな中、webshotパッケージの開発者であるwchは、headless Chromeを使ってスクリーンショットを撮影するwebshot2パッケージをRStudio製OSSとして開発開始しました。
現段階ではCRANに上がっていないので、インストールするにはremotes::install_github("rstudio/webshot2")
を実行して下さい。
開発者が同じなだけあってwebshot2::webshot
関数とwebshot::webshot
関数の引数は同じです。と言うわけで使い方はぞうさんのページを参照して下さい(https://kazutan.github.io/kazutanR/webshot_demo.html)。
Dockerでheadless Chromeが動かない……!
さて、webshot2パッケージではchromoteパッケージを通じてheadless Chromeを動作させているわけですが、docker上で適当なページを撮影しようとすると、以下のようにエラーが返ります。
webshot2::webshot("https://google.com")
#> Error in launch_chrome(path, args) :
#> Failed to start chrome. Error: [0808/182701.557515:ERROR:zygote_host_impl_linux.cc(89)] Running asroot without --no-sandbox is not supported. Seehttps://crbug.com/638180.
どうやら--no-sandbox
を指定すればよさそうですが、セキュリティを低下させるのでお勧めできません1。
docker run時にsecurity_optを弄れば良いらしい
Issueにて解決を図ったところ、pagedownパッケージのドキュメントに記載されている通り、 https://raw.githubusercontent.com/jessfraz/dotfiles/master/etc/docker/seccomp/chrome.json からJSONをダウンロードして、以下のようにdocker runすれば良いと教えてもらいました2。
docker run -e PASSWORD=yourpassword --rm -p 8787:8787 --security-opt seccomp="$(pwd)/chrome.json" myimages/pagedown
docker-composeでできるようにしよう
上述の方法で解決できましたが、コマンド入力が面倒なので、
docker-compose
でできるようにしました。
先述のJSONを
chrome.json
として保存同ディレクトリに
docker-compose.yml
を用意(適宜編集して下さい)version: "3" services: r: image: atusy/atusydown ports: "8787:8787" environment: - ROOT=TRUE - USER=rstudio - PASSWORD=password security_opt: - seccomp:chrome.json
sudo docker-compose up -d
を実行
Docker imageとしてオリジナルのatusy/atusydown
を用いていますが、
webshot2パッケージ以外にも色々入っていて重いです。任意のものを用意して頂いて結構ですが、
chromiumとwebshot2パッケージをインストールした上で、Renviron
にCHROMOTE_CHROME=/usr/bin/chromium
などと記述して下さい。
Enjoy!
無理矢理
--no-sandbox
する方法はこちらに記述しました(https://github.com/rstudio/chromote/issues/20)。アイディアを提供して下さったyutannihilation氏に感謝します。↩︎pagedownのissueを置いかけると、headless Chromeを動かしてる既存のDockerイメージを参考にすれば良いという当たり前なことがわかり、リサーチ不足っぷりを反省しました(justinribeiro/chrome-headless)。↩︎