16
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RubyとSeleniumとFirefoxを使ってWebスクレイピングをする時のtips

Last updated at Posted at 2016-11-08

今までに作ったスクレイピングシステムで得られたノウハウを書く。たまにしかやらないし、目的を達成したらもういじらないし、すぐ忘れるので備忘録として。

使うツール

  • Ruby
    • 楽だし慣れてるから。
    • しかし、Selenium bindingsの対応具合からするとPythonの方がいいような気がする。
  • Selenium
    • Webブラウザをプログラムから操作するためのアイツ。
    • 本来はテスト用のツールのような気がするが、細かいことは気にしない。
    • MechanizeとかPhantomJSとかの、プログラム制御専用の実装もあるが、人様の作ったWebサイトを読み込む場合は、普通のブラウザでないとまともに動かないことが懸念される。特にログインが必要で、かつ限られた人向けのサイトは。
    • 3.0がリリースされてたけど、なんか動かなかったので2.x系を使った。
  • Firefox
    • ESR版を使った。 https://www.mozilla.jp/business/
    • ブラウザとSeleniumとの間でバージョン不整合により動かなくなることがよく起きるので、あまり頻繁に更新したくない。
  • Debian 8
    • Firefox ESR版のパッケージが含まれているメジャーなdistroが他になかった。
    • rpm系は普段使わないので調べてない。
  • docker
    • 時代はコンテナらしいのでがんばってついていきたい。

Implicit Wait と Explicit Wait

昨今のWebサイトはやたらと非同期処理があるので、適切にwaitを入れてやらないと目的のDOMが構築される前に探しに行って、例外が発生してしまう。

今までは適当にsleepとか入れていた(ひどい)のだが、正しい方法がちゃんとあった。

Implicit Wait

これをやっておくと find_element を実行した時、目的の要素が現れるまで「探す→待つ」を繰り返してくれる。指定した秒数を超えるとtimeoutして例外が発生する。 Selenium::WebDriver インスタンス生成時に指定する。

driver = Selenium::WebDriver.for :firefox, :profile => Selenium::WebDriver::Firefox::Profile.new
      browser.manage.timeouts.implicit_wait = 10

Explicit Wait

特定のリクエストについて、特別に長く待ちたい時などに使う。

# まずインスタンスを作る
wait = Selenium::WebDriver::Wait.new(:timeout => 30)

特定の要素が現れるのを待って取得する

e = wait.until { driver.find_element(:xpath, "//input[@name='sometext']") }

要素が clickable になるのを待つ

e = wait.until { e.displayed? && e.enabled? }

Seleniumには ExpectedConditions というクラスがあるらしいのだが、Ruby Selenium bindingsには無いらしい。また clickable というのは要するに displayed? && enabled? のことらしい。 https://stackoverflow.com/a/29903931

テキストボックス(<input type="text" />)に入力する

driver.find_element(:xpath, "//input[@name='sometext']").clear
driver.find_element(:xpath, "//input[@name='sometext']").send_keys("hogehoge")

clear しておいた方が、続けて検索する時とかにハマらなくて済む。

特定の文字列がページ内にあるかチェックする

driver.page_source.match(/ほげほげ/u)

# これは思ったより重い
driver.find_element(:xpath, "//body").innerHTML.match(/ほげほげ/u)

あとがき

なんかあったら追記していく。

16
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?