これは何?
クローラーを作っていると、「特定のaタグの集合から順番にその href
の値にアクセスしていきたい」場面があると思います。
その際に上手く動かなくてハマったことがあったのでその共有と解決策をまとめます。
バージョン
- Ruby: 2.6.4
- selenium-webdriver: 3.142.4
NG例
最初に上手く動かない例です。
elements = @driver.find_elements(xpath: 'aタグを取ってくる何か')
elements.each do |element|
@driver.get(element.attribute('href'))
end
これだと1つ目の element
はアクセスできますが、2つ目以降にアクセスしようとすると以下のようなエラーが発生します。
stale element reference: element is not attached to the page document (Selenium::WebDriver::Error::StaleElementReferenceError)
ドキュメント から現在のページから該当のDOMをアタッチできない(つまり見つけられない?)からエラーになってそうな感じがします。
実際、エラーが起こる時は最初に該当のaタグを取ってきたページと違うページにいるのでそのエラーが起こるのにも納得感があります。
OK例
なので、ループで回す前に飛ぶためのリンクの配列を作ってそれをループで回してアクセスしてけば解決します。
elements = @driver.find_elements(xpath: 'aタグを取ってくる何か')
urls = elements.map {|element| element.attribute('href') }
urls.each do |url|
@driver.get(url)
end