LoginSignup
4
3

More than 5 years have passed since last update.

webスクレイピングを色々試したらseleniumに行きついた。

Last updated at Posted at 2018-12-21

背景

nokogiriやmechanizeでパースしてからxpathを指定で要素を抜き出そうとすると、そのまま動くときと空の配列が返ってくるときがある。
そして、悪いことに目的のサイトでは空の配列が返ってきてしまうパターンだった。

なので色々と調べたところ、目的のサイトでjavascriptが動いているのが良くないらしく、nokogiriとmechanizeでサイトをパースする段階ではjavascript実行前のソースを読み込んでおり、chromeのdevtoolなんかで取得できるxpathは、javascript動作後の動的にhtmlタグが変更された後のものであることが判明。
→存在しないxpathを指定することになるので、空の配列が返ってくるのは期待された動作ということみたい。

p agent.get.bodyを見る限り、欲しい情報はすでに含まれていたので以下の二通りのやり方を検討した。
1.ソースコードから欲しい情報をどうにか指定して抜き出す
2.javascript動かしたあとのhtmlをパースして、chromeなんかで拾えるxpath使う

ざっくり検索かけると、2.のパターンの情報のが多く楽なやり方っぽい。
つまり、seleniumを使うといいらしい。

seleniumで書いたコード

test.rb

#! ruby -Ku
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome
driver.navigate.to '目的のサイトのログインページ'

id = driver.find_element(:xpath,'//*[@id="login_box"]/form/dl/dd[1]/input')
pass = driver.find_element(:xpath,'//*[@id="login_box"]/form/dl/dd[2]/input')

id.send_keys("自分のID")
pass.send_keys("自分のパスワード")

driver.find_element(:xpath,'//*[@id="mainsubmit"]').click
wait = Selenium::WebDriver::Wait.new(timeout: 3)

driver.navigate.to '目的のページ'
wait = Selenium::WebDriver::Wait.new(timeout: 3)

sinchaku = driver.find_elements(:xpath,'//*[@id="main"]/form/table/tbody/tr[1]/td[2]/a')
sinchaku.each do |i|
    puts i.text
end

ほとんど拾い物のコードだけど、javascriptで描画されるサイトで期待通りに動作することを確認できた。
ブラウザで操作する順番で、上からそのまま書いていき、操作したい要素はchromeのdevtoolなんかで見れるxpathで指定していくだけだから簡単。
上記の例だと最後に新着情報の一覧をfind_elementsでとってくるのだけど、そのまま.textメソッドを繋げると配列に対してはundefined methodだと怒られるので、eachで一個づつ要素を取り出して.textメソッドを繋げるとうまくいった。

4
3
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
4
3