在Python中创建自定义等待直到条件

时间:2017-11-21 19:15:42

标签: python selenium selenium-webdriver

我尝试在Python中创建一个具有自定义等待条件的函数。但是,我收到一个错误:

  

TypeError:'bool'对象不可调用

def waittest(driver, locator, attr, value):
    element = driver.find_element_by_xpath(locator)
    if element.get_attribute(attr) == value:
        return element
    else:
        return False
wait = WebDriverWait(driver, 10)
element = wait.until(waittest(driver, '//div[@id="text"]', "myCSSClass", "false"))    

4 个答案:

答案 0 :(得分:2)

我真正要做的就是使用lamba self.wait.until(lambda x: waittest(driver, '//div[@id="text"]', "myCSSClass", "false"))

答案 1 :(得分:1)

它可能无法真正回答问题,我只想在这里保存我的自定义等待函数:D

我不喜欢WebDriverWait(),它需要另一个很难记住或键入的导入,并且还使用了另一个函数来选择元素。

示例:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CLASS_NAME , 'myClass')))

此处自定义等待使用默认功能

import time

def waitFor(maxSecond, runFunction, param):
    while maxSecond:
        try:
            return runFunction(param)
        except:
            time.sleep(0.5)
            maxSecond -= 0.5

用法:

# wait 5 second
waitFor(5, driver.find_element_by_class_name, 'myClass')
# Or
link = waitFor(5, driver.find_element_by_class_name, 'myClass')
link.click()
# Or
link = waitFor(5,....)
if not link:
    print('Timeout, link not found')

供参考

  

查找单个元素

     
      
  • find_element_by_id
  •   
  • find_element_by_name
  •   
  • find_element_by_xpath
  •   
  • find_element_by_link_text
  •   
  • find_element_by_partial_link_text
  •   
  • find_element_by_tag_name
  •   
  • find_element_by_class_name
  •   
  • find_element_by_css_selector
  •   
     

要查找多个元素(这些方法将返回一个列表):

     
      
  • find_elements_by_name
  •   
  • find_elements_by_xpath
  •   
  • find_elements_by_link_text
  •   
  • find_elements_by_partial_link_text
  •   
  • find_elements_by_tag_name
  •   
  • find_elements_by_class_name
  •   
  • find_elements_by_css_selector
  •   

答案 2 :(得分:1)

WebDriverWait(driver, 10).until()接受一个可调用对象,该对象将接受网络驱动程序的一个实例(我们的示例为driver)作为参数。最简单的自定义等待,希望看到2个元素,看起来像

WebDriverWait(driver, 10).until(
    lambda wd: len(wd.find_elements(By.XPATH, 'an xpath')) == 2
)

waittest函数必须重写为:

class waittest:
    def __init__(self, locator, attr, value):
        self._locator = locator
        self._attribute = attr
        self._attribute_value = value

    def __call__(self, driver):
        element = driver.find_element_by_xpath(self._locator)
        if element.get_attribute(self._attribute) == self._attribute_value:
            return element
        else:
            return False

然后可以用作

element = WebDriverWait(driver, 10).until(
    waittest('//div[@id="text"]', "myCSSClass", "false")
)

答案 3 :(得分:-1)

selenium的wait.until(..)函数需要一个可以调用的函数。但是,实际上,你给它一个布尔值。

element = wait.until(waittest(driver, '//div[@id="text"]', "myCSSClass", "false"))

可以改写为:

value = waittest(driver, '//div[@id="text"]', "myCSSClass", "false")
element = wait.until(value)

这使得这更清楚 - waittest返回一个布尔值,wait.until(..)尝试将其称为函数 - 因此'bool' object is not callable

你需要让你的自定义条件返回一个selenium可以调用的函数来检查它是否真实。您可以通过在函数内定义函数来完成此操作:

def waittest(locator, attr, value):
    def check_condition(driver):
        element = driver.find_element_by_xpath(locator)
        if element.get_attribute(attr) == value:
            return element
        else:
            return False
    return check_condition