【问题标题】:How to get a Selenium/Ruby bot to wait before performing an action?如何让 Selenium/Ruby 机器人在执行操作之前等待?
【发布时间】: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 易于使用。

标签: ruby selenium selenium-webdriver webdriver bots


【解决方案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
        

        【讨论】:

          猜你喜欢
          • 2020-11-23
          • 2013-01-17
          • 1970-01-01
          • 2020-11-26
          • 2017-08-11
          • 1970-01-01
          • 1970-01-01
          • 2017-09-18
          • 2021-12-03
          相关资源
          最近更新 更多