我使用Ruby selenium-webdriver
gem创建了一个网络抓取/抓取脚本。我通过AJAX加载我抓取的页面并显示某个帐户的信息。如果您在下拉菜单中选择第二个帐号,页面会非常简短地重定向到另一个URL并返回到原始URL,只需通过AJAX加载不同的信息。我希望能够抓取下拉选项中列出的帐号的信息。问题是,Selenium执行抓取的速度比网页在下拉列表中重定向/重新加载的速度快,因此我不会获得第二个帐户的信息。
def crawl_page
browser = Selenium::WebDriver.for :firefox
browser.manage.timeouts.implicit_wait = 10 # seconds
browser.navigate.to 'http://www.foobar.com'
account_dropdown = Selenium::WebDriver::Support::Select.new(browser.find_element(:id, 'account'))
account_dropdown.options.each do |option|
option.click
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
# this wait is not working because option is selected before redirect/refresh:
wait.until { option.selected? }
html = browser.page_source
scrape_page(html)
end
browser.quit
end
我在点击后尝试在行上放置sleep(3)
,但收到以下错误消息:
[remote server] resource://fxdriver/modules/web_element_cache.js:8180:in `fxdriver.cache.getElementAt': Element not found in the cache - perhaps the page has changed since it was looked up (Selenium::WebDriver::Error::StaleElementReferenceError)
我也尝试使用Selenium的显式wait
代码,但元素的ID似乎在更新后的页面上动态更改,如下所示:
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
wait.until { browser.find_element(:id, 'titlexyz').displayed? }
会出现一条错误消息,指出它已超时,无法找到该元素:
~lib/selenium/webdriver/common/wait.rb:57:in `until': timed out after 10 seconds (Unable to locate element: {"method":"id","selector":"titlexyz"}) (Selenium::WebDriver::Error::TimeOutError)
有没有办法让它入睡或等待,而无需在页面上寻找特定的元素?
答案 0 :(得分:2)
.times
循环。然后在每次迭代中,我为下拉菜单实例化一个新的Selenium对象,找到正确的选项号并单击它。我还让脚本睡了5秒钟,让它有机会进行重载/重定向。
def crawl_page
browser = Selenium::WebDriver.for :firefox
browser.navigate.to 'http://www.foobar.com'
account_dropdown = Selenium::WebDriver::Support::Select.new(browser.find_element(:id, 'account'))
count = account_dropdown.options.count
count.times do |option_num|
account_dropdown = Selenium::WebDriver::Support::Select.new(browser.find_element(:id, 'account'))
account_dropdown.options[option_num].click
sleep 5
html = browser.page_source
scrape_page(html)
end
browser.quit
end
答案 1 :(得分:0)
我不做ruby,所以我无法帮助你使用ruby语法。
每次页面重新加载(每次执行option.click
时都会在您的代码中),您拥有的所有WebElements(您的account_dropdown.find_elements(:css, 'option')
)都不再有效!你必须将你的循环基于其他东西 - 也许是下拉项目的数量 - 并找到你想与内部交互的每个元素!