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

我正在构建一个点击元素的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  

我也尝试过:

 require "watir-webdriver/wait" ... driver.find_element(:class, "gb_P").wait_until.click 

但这也给了我一个未定义的方法错误:

 undefined method `when_present' for # 

您正在使用wait作为WebDriverfunction,但事实并非如此。 试试这个

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

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

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

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

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

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

首先 ,您可以使用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();") 

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

 Task.Delay(1000).Wait(); 

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

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