わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

Ruby + selenium-webdriverで「DevToolsActivePort」を含むエラーが発生する件,とりあえず解決

 RubySelenium Webdriverと,ChromeとChromeDriverを組み合わせて,ユーザ認証が必要なWeb上の情報を,定期的に取得しています.
 しかし最近,「(unknown error: DevToolsActivePort file doesn't exist)」を含むエラーメッセージが出て,アクセスができなくなっていました.
 試行錯誤の末,解決に至りました.簡単にいうと,"--headless"などのオプション指定を,Selenium::WebDriver::Remote::Capabilities.chromeで行うのが,不可になったらしく,代わりにSelenium::WebDriver::Chrome::Optionsを使えば,うまくいきました.
 Ubuntu 18.04 LTSのコマンドライン環境を使用しています.rubygoogle-chrome,chromedriverの各コマンドと,Rubyselenium-webdriverライブラリはそれぞれインストール済みで,実行ファイルの所在やバージョンは以下のとおりです.

$ ruby --version
ruby 2.6.3p63 (2019-06-13 revision 67710) [x86_64-linux]
$ gem list | grep 'selenium-webdriver'
selenium-webdriver (3.142.3)
$ which google-chrome
/usr/bin/google-chrome
$ google-chrome --version
Google Chrome 76.0.3809.87
$ which chromedriver
/home/takehikom/bin/chromedriver
$ chromedriver --version
ChromeDriver 76.0.3809.68 (42以下略)

 失敗するRubyの書き方を,irbの対話環境で1文ずつ実行しながら示します.なお「0x....」は実行のたびに異なる16進数の値で,桁数は4桁ではありません.

$ irb
irb(main):001:0> require "selenium-webdriver"
=> true
irb(main):002:0> Selenium::WebDriver::Chrome::Service.driver_path = File.expand_path("~/bin/chromedriver")
=> "/home/takehikom/bin/chromedriver"
irb(main):003:0> caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {args: ["--disable-dev-shm-usage", "--start-maximized", "--disable-extensions", "--disable-infobars", "--headless", "--disable-gpu", "--no-sandbox", "--window-size=1280x800"]})
=> #<Selenium::WebDriver::Remote::Capabilities:0x.... @capabilities={:browser_name=>"chrome", :version=>"", :platform=>:any, :javascript_enabled=>true, :css_selectors_enabled=>true, :takes_screenshot=>false, :native_events=>false, :rotatable=>false, :firefox_profile=>nil, :proxy=>nil, "chromeOptions"=>{:args=>["--disable-dev-shm-usage", "--start-maximized", "--disable-extensions", "--disable-infobars", "--headless", "--disable-gpu", "--no-sandbox", "--window-size=1280x800"]}}>
irb(main):004:0> driver = Selenium::WebDriver.for :chrome, desired_capabilities: caps
Traceback (most recent call last):
(エラーメッセージ:略)
        1: from #0 0x.... <unknown>
Selenium::WebDriver::Error::UnknownError (unknown error: Chrome failed to start: exited abnormally)
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)

 そして成功した手順です.

$ irb
irb(main):001:0> require "selenium-webdriver"
=> true
irb(main):002:0> Selenium::WebDriver::Chrome::Service.driver_path = File.expand_path("~/bin/chromedriver")
=> "/home/takehikom/bin/chromedriver"
irb(main):003:0> options = Selenium::WebDriver::Chrome::Options.new
=> #<Selenium::WebDriver::Chrome::Options:0x.... @args=#<Set: {}>, @binary=nil, @prefs={}, @extensions=[], @options={}, @emulation={}, @encoded_extensions=[]>
irb(main):004:0> ["--disable-dev-shm-usage", "--start-maximized", "--disable-extensions", "--disable-infobars", "--headless", "--disable-gpu", "--no-sandbox", "--window-size=1280x800"].each { |o| options.add_argument(o) }
=> ["--disable-dev-shm-usage", "--start-maximized", "--disable-extensions", "--disable-infobars", "--headless", "--disable-gpu", "--no-sandbox", "--window-size=1280x800"]
irb(main):005:0> driver = Selenium::WebDriver.for :chrome, options: options
=> #<Selenium::WebDriver::Chrome::Driver:0x.... browser=:chrome>