Joe*_*ano 6 ruby selenium bots webdriver selenium-webdriver
我正在构建一个点击元素的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
Run Code Online (Sandbox Code Playgroud)
但是我收到以下错误:
Undefined method 'wait' for <Selenium::WebDriver>
Run Code Online (Sandbox Code Playgroud)
我也尝试过:
require "watir-webdriver/wait"
...
driver.find_element(:class, "gb_P").wait_until.click
Run Code Online (Sandbox Code Playgroud)
但这也给了我一个未定义的方法错误:
undefined method `when_present' for #<Selenium::WebDriver...>
Run Code Online (Sandbox Code Playgroud)
Guy*_*Guy 10
您正在使用wait的WebDriver功能,但它不是.试试这个
element = wait.until { driver.find_element(:class => "gb_P") }
element.click
Run Code Online (Sandbox Code Playgroud)
好的。这个答案已在许多不同的情况下被多次提出。所以我只想在这里一劳永逸地回答这个问题。
有三种方法可以做到这一点。每一个在某些情况下都是有用的。
首先,您可以使用 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
Run Code Online (Sandbox Code Playgroud)
^ 这将等待:10 秒或直到找到该元素。
其次,您可以使用隐式等待。这与预期条件下的显式等待非常相似。但是,显式等待适用于正在查询的元素,隐式等待适用于WebDriver Object。换句话说,如果您的脚本仅使用单个 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")
Run Code Online (Sandbox Code Playgroud)
第三,您可以调用Javascript函数来单击页面。这样做的优点是,一旦页面的 Javascript 加载,该项目将是可点击的,并且您不必实际等待页面呈现。很多时候,当您“等待页面”时,您实际上是在客户端等待渲染引擎构建页面。您只需在页面实际呈现之前单击底层元素即可绕过该过程。
这样做的缺点是它不能反映真实的人点击页面的情况。例如,如果您要单击的按钮被弹出窗口隐藏。Selenium 不允许您单击它,但 JS 函数可以。
您可以通过执行以下操作来使用此方法:
click = driver.execute_script("document.getElementsByClassName('gb_P')[0].click();")
Run Code Online (Sandbox Code Playgroud)
您是否尝试过使用when时等待按钮(也可以使其等待某个div到达)
require "watir-webdriver/wait"
driver.button(:class => 'gb_P').when_present.click
Run Code Online (Sandbox Code Playgroud)
至于明确的等待
sleep *seconds*
Run Code Online (Sandbox Code Playgroud)
还是不浪费时间的更好方法
sleep *seconds* until driver.element(:id/class/etc, 'value').exists?
Run Code Online (Sandbox Code Playgroud)