GebのWebDriverにPhantomJSを使う

GebでヘッドレスなWebDriverというとHtmlUnitが挙げられますが、JavaScriptのサポートが非常に弱かったり、余計なログを出しまくったりと正直かなり残念な感じです。

FirefoxやChromeを使えばよいのですが、PhantomJSをWebDriverとして使えるようにしたGhost Driverを見つけたのでGebから使ってみたいと思います。

PhantomJSのインストール

まずPhantomJS本体が必要なので、HomeBrew等からインストールしておきましょう。

$ brew install phantomjs
$ phantomjs --version
1.9.1

必要な依存ライブラリについて

今回はGroovyスクリプトからGebを使います。Grapeで依存ライブラリを指定しましょう。

必要なのはGeb本体(geb-core)とPhantomJS Driver(phantomjsdriver)です。
Selenium(selenium-support)はgeb-coreの依存関係から解決されますが、
バージョンが古いので明示的に指定します。

@Grapes([
    @Grab(group='org.gebish', module='geb-core', version='0.9.0'),
    @Grab(group='org.seleniumhq.selenium', module='selenium-support', version='2.33.0'),
    @Grab(group='com.github.detro.ghostdriver', module='phantomjsdriver', version='1.0.3'),
])

それと、PhantomJSのバージョンが1.8系だとphantomjsdriver--webdriver-logfileオプションを渡せないため、
PhantomJSを起動できずにエラーになります。
1.8系で使いたい場合はphantomjsdriverのバージョンを1.0.1にする必要があります。

Gebを呼び出すGroovyスクリプトを書く

ここはPhantomJS Driverであることに関係ありません。

ただし、正常終了時は明示的にSystem.exit()を呼び出しておかないと、
スクリプトが終了しないままになってしまいます。

PhantomJS Driverを使う時だけ発生してしまう事象なのですが、
理由は追っかけていません。

@Grapes([
    @Grab(group='org.gebish', module='geb-core', version='0.9.0'),
    //@Grab(group='org.seleniumhq.selenium', module='selenium-support', version='2.33.0'),
    @Grab(group='com.github.detro.ghostdriver', module='phantomjsdriver', version='1.0.3'),
])

import geb.Browser

Browser.drive {
    // Googleを開く
    go 'https://www.google.co.jp/'
    // Googleが表示されること
    assert title == 'Google'
    report 'google'

    // 'groovy'を検索する
    $('input', name: 'q').value('groovy')
    $('input', value: 'Google 検索').click()
    // 検索結果が表示されること
    waitFor { title =~ /groovy/ }
    report 'google-search-groovy'
    // 最初のリンクがGroovyのWebサイトであること
    def firstLink = $('li.g', 0).find('h3.r').find('a')
    assert firstLink.text() == 'Groovy - Home'

    // 最初のリンクを開く
    firstLink.click()
    // GroovyのWebサイトが表示されること
    waitFor { title == 'Groovy - Home' }
    report 'groovy-website'
}

System.exit(0)

Gebの設定

スクリプトを実行するのと同じディレクトリにGebConfig.groovyを作ります。

import org.openqa.selenium.phantomjs.PhantomJSDriver
import org.openqa.selenium.remote.DesiredCapabilities
import org.openqa.selenium.Dimension

driver = {
    // PhantomJS Driverを使う
    def d = new PhantomJSDriver(new DesiredCapabilities())
    // 画面サイズを1280x1024にする
    d.manage().window().size = new Dimension(1280, 1024)
    d
}

// レポートの出力先を指定する
reportsDir = 'reports'

driverはPhantomJS Driverを単に使うだけであれば、
new PhantomJSDriver(new DesiredCapabilities())だけで構いません。
driverを指定しないとHtmlUnitが使われてしまうのでご注意を。

ここではDriver実装の指定に加えて画面サイズを指定しています。

また、最後にGebのレポートの出力先を設定しています。
これが無いとreportメソッドの呼び出し時にエラーになります。

レポートとしてPNGのスクリーンショットが取得できる

ヘッドレスブラウザですがスクリーンショットが取得できます。
HtmlUnitではできません。

以下は上記スクリプトを実行して出力されたレポートのPNGファイルです。

Google

groovy - Google 検索

Groovy - Home

PhantomJSのインストールが必要ですが、X Window System無しでスクレイピングをするのには良いのではないでしょうか?