古老的问题,但是,
WedDriverWait
在一个独立于 selenium 的示例中,考虑如何工作:
def is_even(n):
return n % 2 == 0
x = 10
WebDriverWait(x, 5).until(is_even)
这将等待最多 5 秒is_even(x)
才能返回True
现在,WebDriverWait(7, 5).until(is_even)
将需要 5 秒,他们会引发 TimeoutException
事实证明,您可以返回任何非 Falsy 值并捕获它:
def return_if_even(n):
if n % 2 == 0:
return n
else:
return False
x = 10
y = WebDriverWait(x, 5).until(return_if_even)
print(y) # >> 10
现在考虑如何EC
工作的方法:
print(By.CSS_SELECTOR) # first note this is only a string
>> 'css selector'
cond = EC.presence_of_element_located( ('css selector', 'div.some_result') )
# this is only a function(*ish), and you can call it right away:
cond(driver)
# if element is in page, returns the element, raise an exception otherwise
您可能想尝试以下方法:
def presence_of_any_element_located(parent, *selectors):
ecs = []
for selector in selectors:
ecs.append(
EC.presence_of_element_located( ('css selector', selector) )
)
# Execute the 'EC' functions agains 'parent'
ecs = [ec(parent) for ec in ecs]
return any(ecs)
如果在中找不到时EC.presence_of_element_located
返回,这将起作用,但它会引发异常,一个易于理解的解决方法是:False
selector
parent
def element_in_parent(parent, selector):
matches = parent.find_elements_by_css_selector(selector)
if len(matches) == 0:
return False
else:
return matches
def any_element_in_parent(parent, *selectors):
for selector in selectors:
matches = element_in_parent(parent, selector)
# if there is a match, return right away
if matches:
return matches
# If list was exhausted
return False
# let's try
any_element_in_parent(driver, 'div.some_result', 'div.no_result')
# if found in driver, will return matches, else, return False
# For convenience, let's make a version wich takes a tuple containing the arguments (either one works):
cond = lambda args: any_element_in_parent(*args)
cond( (driver, 'div.some_result', 'div.no_result') )
# exactly same result as above
# At last, wait up until 5 seconds for it
WebDriverWait((driver, 'div.some_result', 'div.no_result'), 5).until(cond)
我的目标是解释,artfulrobot已经给出了一个片段,用于实际EC
方法的一般使用,请注意
class A(object):
def __init__(...): pass
def __call__(...): pass
只是定义函数的一种更灵活的方式(实际上是“类函数”,但在这种情况下无关紧要)