読者です 読者をやめる 読者になる 読者になる

kurukuru-papaのブログ

主に、ソフトウェア開発に関連したメモを書き溜めたいと思います。

ラズパイでRubyのWebクローリング/スクレイピング環境構築メモ(後半)

Ruby

前回の続きです。

前回は、OSアップデートから、Rubyのインストールまでの手順を書きました。今回は、Webクローリング/スクレイピングするためのRubyジェムをインストールする手順です。

Rubyジェムインストール(Selenium-WebDriver,Nokogiri)

RubyでWebクローリング/スクレイピングするのに便利なジェムとして、Selenium-WebDriver、Nokogiriをインストールすることにしました。インストールは、次のように行いました。

$ gem install selenium-webdriver
$ gem install nokogiri

Selenium-WebDriverが動作するように次の設定を行いました。この設定が必須なのかどうかは不明です。

$ sudo vi /etc/hosts
$ diff /etc/hosts.bk20160403 /etc/hosts
2,6c2,6
< ::1           localhost ip6-localhost ip6-loopback
< fe00::0               ip6-localnet
< ff00::0               ip6-mcastprefix
< ff02::1               ip6-allnodes
< ff02::2               ip6-allrouters
---
> #::1          localhost ip6-localhost ip6-loopback
> #fe00::0              ip6-localnet
> #ff00::0              ip6-mcastprefix
> #ff02::1              ip6-allnodes
> #ff02::2              ip6-allrouters

Selenium-WebDriverから制御可能なブラウザとして、Firefoxを使うことにしました。Linuxの世界では、Firefoxの代替(?)が、Iceweaselらしいので次のようにしてインストールしました。

$ sudo apt-get install iceweasel

ここまでの手順で、ラズパイのX端末環境において、RubyでWebクローリング/スクレイピングができるようになりました。ただし、X端末が必要ですし、Selenium-WebDriver動作時にはブラウザが画面表示されます。これだと、CUI環境で動作させることはできませんでした。

トラブル体験

hostsファイルのIPv6設定を有効にしたまま、RubyジェムのSelenium-WebDriverを使うと、次のようなエラーが発生しました。

/home/xxx/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/common/port_prober.rb:47:in `initialize': Address family not supported by protocol - socket(2) for "::1" port 7055 (Errno::EAFNOSUPPORT)

このエラーは、次のページをみて解決することができました。感謝!

blog.livedoor.jp

Firefox(Iceweasel)をインストールせずに、RubyジェムのSelenium-WebDriverを使うと、次のようなエラーが発生しました。

/home/xxx/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/firefox/binary.rb:150:in `path': Could not find Firefox binary (os=linux). Make sure Firefox is installed or set the path manually with Selenium::WebDriver::Firefox::Binary.path= (Selenium::WebDriver::Error::WebDriverError)

このエラー発生時には、次のページにお世話になりました。このぺーじでIceweaselの存在を知り、インストール方法が分かりました。

assimane.blog.so-net.ne.jp

ここまでの手順の状態(CUI環境で動作させるための環境構築を未実施)にも関わらず、CUI環境でRubyジェムのSelenium-WebDriverを使うと、次のようなエラーが発生しました。

/home/xxx/.rbenv/versions/2.2.4/lib/ruby/gems/2.2.0/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/firefox/launcher.rb:90:in `connect_until_stable': unable to obtain stable firefox connection in 60 seconds (127.0.0.1:7055) (Selenium::WebDriver::Error::WebDriverError)

このとき、次のページを見つけて、Headlessの存在を知りました。

Raspberry PiでSeleniumを使ってスクレイピング | あっかぎのページ

Rubyジェムインストール(Headless)

今回初めて知ったのですが、Selenium-WebDriverをCUI環境で動作させるためには、Headlessというジェムがありました。次のようにして、Headlessジェムと、そのジェムを動作させるためのライブラリ類をインストールしました。

$ sudo apt-get install xvfb
$ gem install headless
$ sudo vi /etc/modprobe.d/ipv6.conf
$ diff /etc/modprobe.d/ipv6.conf.bk20160403 /etc/modprobe.d/ipv6.conf
3c3,4
< #alias ipv6 off
---
> alias ipv6 off

これで、CUI環境でも、Selenium-WebDriverが動作するようになりました。

トラブル体験

Selenium-WebDriverでブラウザを上手く起動できない時がありました。その場合、`export DISPLAY=:99`としてから、動作させると上手く起動できました。でも、最終的にはその手順をしなくても動作するようになりましたので、必須の手順ではないようです。

Selenium-WebDriverでWebクローリングしたところ、取得したWebページが英語表記になってしまうことがありました。その場合は、Rubyスクリプトで次のようにすることで解決しました。

profile = Selenium::WebDriver::Firefox::Profile.new
profile['intl.accept_languages'] = "ja"
profile['general.useragent.locale'] = "ja-JP"
driver = Selenium::WebDriver.for :firefox, :profile => profile

この際は、こちらのページに助けられました。

qiita.com

Selenium-WebDriverでWebクローリングしたところ、画面表示に時間がかかるページがあり、次のようなエラーが発生しました。

/home/xxx/.rbenv/versions/2.2.4/lib/ruby/2.2.0/net/protocol.rb:158:in `rescue in rbuf_fill': Net::ReadTimeout (Net::ReadTimeout)

その場合、Rubyスクリプトで次のようにすると解決しました。

# タイムアウト値を大きくする(デフォルトは60秒。)
client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 120
driver = Selenium::WebDriver.for :firefox, :http_client => client

この際は、こちらのページに助けられました。

qiita.com

おわり

非常に手間と時間がかかりましたが、環境構築を無事完了できてよかった。