2013-05-09 55 views
13

我使用硒2/webdriver的使用Python API,如下所示:硒预期条件 - 可能使用'或'?

from selenium.webdriver.support import expected_conditions as EC 

# code that causes an ajax query to be run 

WebDriverWait(driver, 10).until(EC.presence_of_element_located(\ 
    (By.CSS_SELECTOR, "div.some_result"))); 

我想等要么结果被返回(div.some_result“未找到”字符串。那可能吗?种:

WebDriverWait(driver, 10).until(\ 
    EC.presence_of_element_located(\ 
     (By.CSS_SELECTOR, "div.some_result")) \ 
    or 
    EC.presence_of_element_located(\ 
     (By.CSS_SELECTOR, "div.no_result")) \ 
); 

我知道我可以使用CSS选择器(div.no_result, div.some_result)做到这一点,但有没有办法用料条件方法硒办呢?

+0

看看这个http://stackoverflow.com/questions/7781792/selenium- waitforelement,可以帮助你.. – 2013-05-09 12:56:28

+0

ExpectedConditions类是一个整洁的一切,但我已经知道它不是非常可靠的(纯粹的形式),你需要明确地捕捉使用它的有关例外情况,有时循环到重试失败。 – djangofan 2013-05-09 23:39:12

回答

12

我做了这样的:

class AnyEc: 
    """ Use with WebDriverWait to combine expected_conditions 
     in an OR. 
    """ 
    def __init__(self, *args): 
     self.ecs = args 
    def __call__(self, driver): 
     for fn in self.ecs: 
      try: 
       if fn(driver): return True 
      except: 
       pass 

然后调用它像...

from selenium.webdriver.support import expected_conditions as EC 
# ... 
WebDriverWait(driver, 10).until(AnyEc(
    EC.presence_of_element_located(
     (By.CSS_SELECTOR, "div.some_result")), 
    EC.presence_of_element_located(
     (By.CSS_SELECTOR, "div.no_result")))) 

显然,这将是微不足道的同样也实施AllEc类。

Nb。 try:区块很奇怪。我很困惑,因为一些EC返回true/false,而其他的会抛出False的异常。 WebDriverWait捕获异常,所以我的AnyEc产生了奇怪的结果,因为第一个抛出异常意味着AnyEc没有进入下一个测试。

-2

尝试使用lambda表达式:

WebDriverWait(driver, 10).until(lambda a:
a.presence_of_element_located(By.CSS_SELECTOR, "div.some_result") OR a.presence_of_element_located(By.CSS_SELECTOR, "div.no_result"))

1

古老的问题,而是,

考虑如何WedDriverWait的作品,在一个例子独立硒:

def is_even(n): 
    return n % 2 == 0 

x = 10 

WebDriverWait(x, 5).until(is_even) 

这将等待秒钟返回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 

你可能会想尝试一些喜欢的东西E:

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返回Falseparent没有发现selector,但它抛出一个异常,易于理解的解决办法是:

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 sel 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: 
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 

只是一个更灵活的方式来定义函数(实际上,'功能样',但在这种情况下,这是无关的)