如何让 Selenium/Ruby 机器人在执行操作之前等待?
Posted
技术标签:
【中文标题】如何让 Selenium/Ruby 机器人在执行操作之前等待?【英文标题】:How to get a Selenium/Ruby bot to wait before performing an action? 【发布时间】:2016-06-16 03:49:21 【问题描述】:我正在构建一个单击元素的 Selenium/Ruby 网络机器人。问题是,有时在机器人决定它找不到元素之前没有足够的时间加载页面。
在执行操作之前让 Selenium 等待的 Ruby 方法是什么?我更喜欢显式等待,但我也可以接受隐式等待。
我尝试使用wait.until
方法:
require "selenium-webdriver"
require "nokogiri"
driver = Selenium::WebDriver.for :chrome
wait = Selenium::WebDriver::Wait.new(:timeout => 15)
driver.navigate.to "http://google.com"
driver.wait.until.find_element(:class, "gb_P").click
但我收到以下错误:
Undefined method 'wait' for <Selenium::WebDriver>
我也试过了:
require "watir-webdriver/wait"
...
driver.find_element(:class, "gb_P").wait_until.click
但这也给了我一个未定义的方法错误:
undefined method `when_present' for #<Selenium::WebDriver...>
【问题讨论】:
如果你刚刚开始,切换到水豚。 Capybara 默认等待,在后台使用 selenium(或其他驱动程序),API 易于使用。 【参考方案1】:随便用
sleep(number_of_seconds)
那你就等着吧。
【讨论】:
【参考方案2】:你有没有试过当出现时,等待按钮(你也可以让它等待某个 div 到)
require "watir-webdriver/wait"
driver.button(:class => 'gb_P').when_present.click
至于显式等待
sleep *seconds*
或者更好的方式来不浪费时间
sleep *seconds* until driver.element(:id/class/etc, 'value').exists?
【讨论】:
它给了我一个“未定义的方法`when_present'”错误。 我认为您实际上指的是显式等待。【参考方案3】:好的。这个答案在许多不同的情况下被问过很多次。所以我只想在这里一劳永逸地回答。
这可以通过三种方式完成。并且每一个都在某些情况下很有用。
首先,您可以使用显式等待。这与页面是否加载无关。它只是告诉脚本等待。换言之,如果您的页面加载时间为 11 秒,而您的显式等待时间为 10 秒,则可点击元素 still 将不可用。您可以通过使用预期条件来解决这种低效率问题。例如,参见 Selenium 联机帮助页:
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
driver.get "http://google.com"
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
begin
element = wait.until driver.find_element(:class => "gb_P")
ensure
driver.quit
end
^ 这将等待:10 秒或直到找到元素。
第二,你可以使用隐式等待。这与具有预期条件的显式等待非常相似。但是,显式等待适用于被查询的元素,隐式等待适用于 WebDriver 对象。换句话说,如果您的脚本只使用一个 webdriver,它将等待:每个元素的隐式等待时间或直到找到每个元素(直到失败)。例如:
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :firefox
driver.manage.timeouts.implicit_wait = 10 # seconds
driver.get "http://google.com"
element = driver.find_element(:class => "gb_P")
第三,可以调用javascript函数来点击页面。这样做的好处是一旦页面的 Javascript 加载,该项目将是可点击的,您不必真正等待页面呈现。很多时候,当您“等待页面”时,实际上是在 客户端 端等待渲染引擎构建页面。您可以通过在页面实际呈现之前简单地单击底层元素来绕过该过程。
这样做的缺点是它不能反映实际的人类点击页面。例如,如果您要单击的按钮被弹出窗口隐藏。 Selenium 不允许你点击它,但是一个 JS 函数可以。
您可以通过以下方式使用此方法:
click = driver.execute_script("document.getElementsByClassName('gb_P')[0].click();")
【讨论】:
【参考方案4】:可能的答案在您的堆栈跟踪中。
driver.element(:class, "gb_P").when_present.click
【讨论】:
【参考方案5】:您正在使用wait
作为WebDriver
函数,但事实并非如此。试试这个
element = wait.until driver.find_element(:class => "gb_P")
element.click
【讨论】:
以上是关于如何让 Selenium/Ruby 机器人在执行操作之前等待?的主要内容,如果未能解决你的问题,请参考以下文章
Selenium+Ruby 实例分析 - 京东抢券 2 处理cookie
Net::ReadTimeout (Net::ReadTimeout) Selenium Ruby