cygwin+rubyでselenium-webdriverがうまく動かなかった

自分用のメモ

スクレイピングがしたかった

Rubyのgemsの1つ、selenium-webdriver を使ってWebスクレイピングをやりたかったので色々と参考にしながら動かしていた。ただ、Windowsから動かす分には問題なかったものの、Cygwin64 Terminal上ではよくわからんエラーを吐かれてしまったため長い長い原因探しの旅に出ることになってしまた。

Cygwin初心者の夜は長い

いろいろ原因を探ってみるとWindowsCygwin上でそれぞれ動いているRubyのバージョンが違っていたらしかったので1、とりあえずCygwin上でRubyをこんな感じ↓で2.6.3にアップデートした後、

$ cd
$ git clone git://github.com/sstephenson/rbenv.git .rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ source ~/.bashrc
$ mkdir -p ~/.rbenv/plugins
$ cd ~/.rbenv/plugins
$ git clone git://github.com/sstephenson/ruby-build.git
$ rbenv install 2.6.3
$ rbenv rehash
$ rbenv global 2.6.3

再度こんな風に実行してみたものの↓

$ ruby ./selenium_test.rb

エラーがどばどば↓

Traceback (most recent call last):
        17: from ./selenium_test.rb:13:in `<main>'
        16: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver.rb:88:in `for'
        15: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/driver.rb:54:in `for'
        14: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/firefox/driver.rb:33:in `new'
        13: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/firefox/driver.rb:33:in `new'
        12: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/firefox/marionette/driver.rb:38:in `initialize'
        11: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/driver.rb:299:in `service_url'
        10: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/service.rb:58:in `firefox'
         9: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/service.rb:58:in `new'
         8: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/service.rb:94:in `initialize'
         7: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/service.rb:134:in `binary_path'
         6: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/platform.rb:161:in `find_binary'
         5: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/platform.rb:161:in `each'
         4: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/platform.rb:162:in `block in find_binary'
         3: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/platform.rb:162:in `each'
         2: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/platform.rb:164:in `block (2 levels) in find_binary'
         1: from /cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/platform.rb:122:in `unix_path'
/cygdrive/c/Users/$USERNAME/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/platform.rb:122:in `tr': no implicit conversion of nil into String (TypeError)

おえぇ…

Ruby完全に理解していないのでよくわからなかったものの、nilからStringにtrメソッドで変換できない的なことを仰っているので該当する行(platform.rb:122)を調べるとこんな感じになっていた↓

...

      def unix_path(path)
        path.tr(File::ALT_SEPARATOR, File::SEPARATOR)
      end

...

どうやらFile::ALT_SEPARATORはCygwin上でnilを返すらしく、それがだめっぽい

とりあえずnilじゃなくて空文字列を返すようにすればいけそうなので自分の実行ファイル(selenium_test.rb)に以下の行を追加してみた↓

File::ALT_SEPARATOR = ""

これをCygwin上で実行すると、警告は表示されるものの↓

./selenium_test.rb:3: warning: already initialized constant File::ALT_SEPARATOR  

ひとまず動いた、が今度はWindows上で動かなくなった(そりゃそうだ)

かなり強引なやり方なので良い方法ではなさそうだが…

参考にしたサイト

www.oiax.jp

constant File::ALT_SEPARATOR (Ruby 2.6.0)


  1. Windows上では2.6.1p33、Cygwin上では2.3.6p384