Selenium と Ruby によりテストの自動化であったり、入力の自動化を進めている。
コマンドラインから実行すればよいことがほとんどで、ブラウザのGUIが起動しなくてもよい。
したがって、GUI が起動しない Google Chrome の Headless モードを使った Selenium スクリプトへ順次移行していこうと思う。
動作の軽量化もちょっとは期待できるかも。 (比較計測はしていない)
以下は、関連記事。
環境情報
ソフトウェア
バージョン
OS
Windows 10 Pro 1709
ブラウザ
Google Chrome 69.0.3497.100
ChromeDriver
2.39.562718
ruby
2.5.1p57
gem selenium-webdriver
(3.14.1, 3.12.0)
Ruby と gem はインストールされているものとする。
Chrome headless モードの動作確認
Chrome のバージョン59以降からヘッドレスモードを搭載している。
Chrome をインストールしていない場合は、インストールする。
動作確認はコマンドライン (Powershell or コマンドプロンプト) から可能で、以下のように動けば OK。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
> cd "C:\Program Files (x86)\Google\Chrome\Application"
> ls
ディレクトリ: C:\Program Files (x86)\Google\Chrome\Application
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2018/09/21 19:12 69.0.3497.100
d----- 2018/09/25 16:45 SetupMetrics
-a---- 2018/09/15 17:47 1378648 chrome.exe
-a---- 2018/09/25 16:45 410 chrome.VisualElementsManifest.xml
-a---- 2018/05/17 17:06 122574 master_preferences
> .\chrome.exe --enable-logging --headless --disable-gpu --dump-dom https://www.chromestatus.com
<!DOCTYPE html>
<html lang="en"><head>
<meta charset="utf-8">
<title>Chrome Platform Status</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="manifest" href="/static/manifest.json">
... (snip) ...
Proxy 環境下にいる場合は、--proxy-server
や --proxy-auth
オプションで指定してあげればよい。
1
> .\chrome.exe --enable-logging --headless --disable-gpu --dump-dom --proxy-server=http://PROXY_HOST:PORT --proxy-auth=USER:PASSWORD https://www.chromestatus.com
詳細は ヘッドレス Chrome ことはじめ | Web | Google Developers のあたりを参照。
ChromeDriver
Selenium WebDriver は Selenium から Web ブラウザをコントロールするライブラリ群。
各ブラウザ向けに実装されていて、ChromeDriver は Chrome 用の WebDriver。
以下から入手し、PATHを通す。(もしくは通っているところに置く)
コンソールからバージョンが表示できれば PATH 設定の確認になる。
1
2
> chromedriver.exe -v
ChromeDriver 2.39.562718 (9a2698cba08cf5a471a29d30c8b3e12becabb0e9)
Selenium スクリプト
サンプルとして、本ブログのいくつかのページのスクリーンショットを取得する。
http://momota.github.io/blog/page/2/ ~ http://momota.github.io/blog/page/4/ のスクリーンショットを取得してみる。
Headless モードといっても特段難しいことはなく、以下のように Webdriver にオプションしてあげるだけでよい。
1
2
3
4
5
6
options = Selenium : :WebDriver :: Chrome : :Options . new
options . add_argument ( '--headless' )
options . add_argument ( '--disable-gpu' )
options . add_argument ( '--window-size=1929,2160' )
driver = Selenium : :WebDriver . for :chrome , options : options
Proxy の設定が必要な場合は、以下のようにオプションで指定する。
環境変数 ENV['http_proxy']
に設定してもだめなので注意。
1
2
3
4
5
6
7
8
+ proxy_host = 'PROXY_HOST'
+ proxy_port = 'PORT'
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1929,2160')
+ options.add_argument("--proxy-server=http://#{proxy_host}:#{proxy_port}")
スクリプトとしては以下のような感じ。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# conding: utf-8
require 'selenium-webdriver'
require 'fileutils'
class Blog
SCREENSHOT_DIR = './screenshot/'
def initialize
proxy_host = 'PROXY_HOST'
proxy_port = 'PORT'
options = Selenium : :WebDriver :: Chrome : :Options . new
options . add_argument ( '--headless' )
options . add_argument ( '--disable-gpu' )
options . add_argument ( '--window-size=1929,2160' )
options . add_argument ( "--proxy-server=http:// #{ proxy_host } : #{ proxy_port } " )
@driver = Selenium : :WebDriver . for :chrome , options : options
@base_url = 'http://momota.github.io/'
@accept_next_alert = true
@driver . manage . timeouts . implicit_wait = 20
@verification_errors = []
FileUtils . mkdir ( SCREENSHOT_DIR ) unless Dir . exist? ( SCREENSHOT_DIR )
end
def get_and_screenshot
( 2 . . 4 ) . each do | i |
@driver . get ( " #{ @base_url } blog/page/ #{ i } /" )
@driver . save_screenshot ( " #{ SCREENSHOT_DIR } headless_ #{ i } .png" )
puts "access and save screenshot: #{ i } "
end
end
def close
@driver . quit
end
end
# ----------------------------------------------------------------------
# main
# ----------------------------------------------------------------------
if __FILE__ == $PROGRAM_NAME
blog = Blog . new
blog . get_and_screenshot
end
普通に ruby script.rb
で実行すると、スクリーンショット 実行ディレクトリ/screeshot/headless_i.png
が出力される。
1
2
3
4
5
6
7
8
9
10
11
PS > ls . \ screenshot \
ディレクトリ : C :\ SOMEWHERE \ screenshot
Mode LastWriteTime Length Name
---- ------------- ------ ----
- a ---- 2018 / 10 / 16 12 : 39 438601 headless_2 . png
- a ---- 2018 / 10 / 16 12 : 39 405054 headless_3 . png
- a ---- 2018 / 10 / 16 12 : 39 399793 headless_4 . png