ブラウザを自動化して処理する必要があったので Headless Chrome を Windows Subsystem for Linux で動く Ubuntu 18.04 に導入してみた。
基本的なやり方は以前行った Ubuntu での導入方法と同じ。WSL 用にちょっと変えたりエラーが出たところを修正したりした。
さくらの VPS 上の Ubuntu で Headless Chrome を動かすUbuntu 18.04 に Headless Chrome をインストールする
まずは必要なものを入れる。
$ sudo apt-get install libappindicator1 fonts-liberation
Google Chrome は Google より最新安定版をダウンロードしインストールする。
$ curl -O https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
$ sudo dpkg -i google-chrome-stable_current_amd64.deb
Selecting previously unselected package google-chrome-stable.
(Reading database ... 54009 files and directories currently installed.)
Preparing to unpack google-chrome-stable_current_amd64.deb ...
Unpacking google-chrome-stable (69.0.3497.100-1) ...
dpkg: dependency problems prevent configuration of google-chrome-stable:
google-chrome-stable depends on libappindicator3-1; however:
Package libappindicator3-1 is not installed.
(省略)
dpkg: error processing package google-chrome-stable (--install):
dependency problems - leaving unconfigured
Processing triggers for man-db (2.8.3-2) ...
Processing triggers for mime-support (3.60ubuntu1) ...
Errors were encountered while processing:
google-chrome-stable
長いので省略したが、インストールしようとしたらあれこれパッケージが無いと言われてしまった。指定のあったパッケージをインストールしよう。
$ sudo apt-get install libappindicator3-1 libasound2 libatk-bridge2.0-0 libgtk-3-0 libnspr4 libnss3 libx11-xcb1 libxss1 libxtst6 xdg-utils
Reading package lists... Done
Building dependency tree
Reading state information... Done
You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies:
libappindicator3-1 : Depends: libdbusmenu-gtk3-4 (>= 0.4.2) but it is not going to be installed
(省略)
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).
今度は別のエラーが出てインストールできない。apt --fix-broken install を試せとあるのでそのようにする。
$ sudo apt --fix-broken install
Reading package lists... Done
Building dependency tree
Reading state information... Done
Correcting dependencies... Done
The following additional packages will be installed:
(以下略)
これで再度 sudo dpkg -i google-chrome-stable_current_amd64.deb
を実行するとインストールできた。
ちゃんと実行できるか試してみよう。といっても Headless なのでスクショを撮って確認する。
$ google-chrome --headless --disable-gpu --screenshot http://b.hatena.ne.jp/
[0929/221440.540860:ERROR:gpu_process_transport_factory.cc(1007)] Lost UI shared context.
[0929/221446.401940:INFO:headless_shell.cc(538)] Written to file screenshot.png.
$ mv screenshot.png /mnt/c/Dropbox/images/.
何やらエラーは出たし日本語のフォントは豆腐になっているが、スクリーンショットは撮れたので Headless Chrome の動作には問題ないだろう。
WSL Ubuntu 18.04 に日本語フォントをインストールする
日本語を表示するためにフォントを入れよう。
といってもフォント自体は Windows 側に大量にあるのでシンボリックリンクをはるだけだ。
$ sudo ln -s /mnt/c/Windows/Fonts/ /usr/share/fonts/windows
$ fc-cache -fv
この状態で先程と同じようにスクリーンショットを撮ると日本語フォントが読み込まれているのがわかる。
Headless Chrome を Ruby で操作する
なぜ Headless Chrome 動かすのかというと今開発中の Rails アプリで必要になるからなので Ruby から操作できるようにする。必要になるのは ChromeDriver と Selenium, Nokogiri の3つ。それぞれインストールする。
まずは ChromeDriver をインストールする。先程インストールした Google Chrome のバージョンにあったものをインストールしないといけないので、確認して対応するバージョンをダウンロードし、インストールしよう。
$ google-chrome --version
Google Chrome 69.0.3497.100
Google Chrome のバージョンは 69 なのでそれに対応する 2.42 を利用する。
Downloads - ChromeDriver - WebDriver for Chrome$ curl -O https://chromedriver.storage.googleapis.com/2.42/chromedriver_linux64.zip
$ unzip chromedriver_linux64.zip
Archive: chromedriver_linux64.zip
inflating: chromedriver
$ chmod +x chromedriver
$ sudo mv -f chromedriver /usr/local/share/chromedriver
$ sudo ln -s /usr/local/share/chromedriver /usr/local/bin/chromedriver
$ sudo ln -s /usr/local/share/chromedriver /usr/bin/chromedriver
$ chromedriver
Starting ChromeDriver 2.42.591071 (0b695ff80972cc1a65a5cd643186d2ae582cd4ac) on port 9515
Only local connections are allowed.
chromedriver コマンドがエラー出ず動けば OK
あとは Ruby Gem から必要なものをインストールする。
$ gem install selenium-webdriver
$ gem install nokogiri
これで準備OK, テスト用にスクリプトを走らせてみる。
require 'selenium-webdriver'
require 'nokogiri'
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3163.100 Safari/537.36"
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {
binary: '/usr/bin/google-chrome',
args: ["--headless",
"--disable-gpu",
"--user-agent=#{ua}",
"window-size=1280x800"]})
session = Selenium::WebDriver.for :chrome, desired_capabilities: caps
session.manage.timeouts.implicit_wait = 30
session.navigate.to "https://www.google.co.jp/"
id = session.find_element(:name, 'q')
id.send_keys("headless chrome")
id.send_keys("\n")
session.save_screenshot('screenshot.png')
簡単に解説すると Google を開いて "headless chrome" で検索した結果をスクリーンショットに撮っている。
screenshot.png を開いてこのような感じになっていれば成功だ。