如何在执行操作之前让Selenium / Ruby bot等待?

时间:2016-03-03 01:51:45

标签: ruby selenium selenium-webdriver webdriver bots

我正在构建一个点击元素的Selenium / Ruby Web机器人。问题是,在机器人决定无法找到元素之前,有时候页面没有足够的时间加载。

在执行操作之前,让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...>

7 个答案:

答案 0 :(得分:8)

您正在使用wait作为WebDriver功能,但它并非如此。试试这个

element = wait.until { driver.find_element(:class => "gb_P") }
element.click

答案 1 :(得分:4)

你有没有尝试过现在,等待按钮(你也可以让它等待某个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?

答案 2 :(得分:2)

好。在许多不同的背景下,已经多次询问过这个答案。所以我只想一劳永逸地回答这个问题。

有三种方法可以做到这一点。每种情况在某些情况下都很有用。

首先 ,您可以使用EXPLICIT等待。这与页面是否加载无关。它只是告诉脚本等待。换句话说,如果您的页面在11秒内加载并且您的显式等待时间为10秒,则可点击元素仍然将不可用。您可以通过使用预期条件来解决这种低效问题。参见,例如,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();")

答案 3 :(得分:1)

潜在的答案在你的堆栈跟踪中。

driver.element(:class, "gb_P").when_present.click

答案 4 :(得分:0)

使用Webdriver RC和C#我发现这是使驱动程序等待的最有效方法:

iconBar/Site

答案 5 :(得分:0)

只需使用

sleep(number_of_seconds)

然后您可以等待它。

答案 6 :(得分:-1)

你也可以简单地使用sleep(#)这会让它等待,并且根据你的编辑器,你可以看到你可以使用哪些变体,而不是秒,你可以去更低或更高的东西,在Ruby中你不要# 39;甚至不得不宣布它。

只需在括号中键入sleep和一个数字,您应该看到它在几秒钟内停止了这段时间,其他人注意到为什么这是一个可能不是最佳的解决方案,但如果您只需要等待一点在一个永远不会花费很长时间的页面上,它可以使用很棒的一行代码。