Ruby Selenium Webdriver - 睡眠而不是等待

时间:2017-07-11 12:39:05

标签: ruby selenium selenium-webdriver

我正在使用 Ruby selenium-webdriver gem来创建网络抓取/抓取脚本。我在项目上已经完成了很多但是仍然坚持了一点 我正在抓取的网站使用页面调用服务器并显示一个字符串,问题是它显示50%的次数而不是100%。所以我需要循环get函数,直到它显示字符串。

我使用了隐含&显式等待,但它们都在条件>>中工作等到>>条件>> {要么在条件 TRUE 之后继续,要么引发异常},这会在50%的情况下破坏我的脚本

#throws exception after timout

wait = Selenium::WebDriver::Wait.new(:timeout => 10) 
wait.until { driver.find_element(:id, 'message').displayed? }

我需要的是>>睡眠直到>>条件{在条件 true 之后继续,或者执行代码再次调用字符串

#continues to next block of code after timout

sleep = Selenium::WebDriver::Sleep.new(:timeout => 10) 
sleep.until { driver.find_element(:id, 'message').displayed? } do
   ##RUN CODE TO CALL THE STRING AGAIN##
end

我可以使用正常的 sleep 10 并且工作正常但是如果调用首先返回字符串则浪费时间

#normal Sleep

sleep 10
driver.find_element(:id, 'message').displayed? 

3 个答案:

答案 0 :(得分:1)

# Method will either interrupt waiting when condition is truthy,
# or it will throw Timeout error after N seconds
def wait_until(timeout = DEFAULT_WAIT_TIME)
  Timeout.timeout(timeout) do
    sleep(0.1) until value = yield
    value
  end
end

# usage
wait_until(10) { driver.find_element(:id, 'message').displayed? }

答案 1 :(得分:1)

显然我自己解决了;)感谢你的帮助,硒中没有“sleep.until”这样的东西。解决方案是处理异常并采取相应行动。

wait = Selenium::WebDriver::Wait.new(:timeout => 10)

def run 
  ##code to retrieve message

  begin
    wait.until { driver.find_element(:id, 'message').displayed? } #check if message received
  rescue
    ##this block get's executed if there is any kind of exception error
    run
  end

end

答案 2 :(得分:0)

我的解决方案

虽然您的解决方案确实有效,但我想提出另一种解决方案:

def element_is_displayed?(by, value)

  # Can I find any elements on the page matching what I've been given?
  if driver.find_elements({by => value})[0] != nil
    # Got a match, is it displayed?
    driver.find_element({by => value}).displayed?
  else
    # No matches found
    false 
  end
end

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { element_is_displayed?("id", "message") }

解释

element_is_displayed?函数将尝试查找给定值的至少1个匹配项,如果找不到匹配项,或者未显示该元素,则它将在{{{{1}内执行循环1}}

因为此函数总是返回一个布尔值,所以它适合在selenium wait.until方法中使用,该方法仅在满足超时或返回truthy值时返回。

另一个好处是这个函数是可重用的:尽可能保持函数的可配置性,你仍然可以通过selenium(css,id,xpath等)本地的任何东西找到元素。

这也意味着如果元素由于某种原因(例如浏览器没有加载页面)根本不存在于页面上,那么该函数不会不断循环(您可能会在几个小时内执行此操作,因为它会解除未找到的"元素"错误并再次运行自己。)

希望这有帮助。