implicitly_wait(): 是 webdirver 提供的一个超时等待。隐的等待一个元素被发现, 或一个命令完成。
如果超出了设置时间的则抛出异常。
需要特别说明的是:隐性等待对整个 driver 的周期都起作用,所以只要设置一次即可,我曾看到有人把隐性等待当成了 sleep 在用,走哪儿都来一下…
WebDriverWait()
详细格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver -
WebDriver 的驱动程序 (Ie, Firefox, Chrome 或远程)
timeout - 最长超时时间, 默认以秒为单位
poll_frequency -
休眠时间的间隔 (步长) 时间, 默认为 0.5 秒
ignored_exceptions -
超时后的异常信息, 默认情况下抛 NoSuchElementException 异常。
实例:
- from selenium.webdriver.support.ui import WebDriverWait
- ....
- element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("someId"))
- is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).
- until_not(lambda x: x.find_element_by_id("someId").is_displayed())
WebDriverWai() 一般由 unit() 或 until_not() 方法配合使用, 下面是 unit() 和 until_not() 方法的说明。
until(method, message=' ')
调用该方法提供的驱动程序作为一个参数, 直到返回值不为 False。
until_not(method, message=' ')
调用该方法提供的驱动程序作为一个参数, 直到返回值为 False。
第三种办法就是显性等待,WebDriverWait,配合该类的 until() 和 until_not() 方法,就能够根据判断条件而进行灵活地等待了。它主要的意思就是:程序每隔 xx 秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出 TimeoutException。
先看个代码实例:
- # -*- coding: utf-8 -*-
- fromselenium importwebdriver
- fromselenium.webdriver.support.wait importWebDriverWait
- fromselenium.webdriver.support importexpected_conditions as EC
- fromselenium.webdriver.common.by importBy
- driver=webdriver.Firefox()
- driver.implicitly_wait(10)# 隐性等待和显性等待可以同时用,但要注意:等待的最长时间取两者之中的大者
- driver.get('https://huilansame.github.io')
- locator=(By.LINK_TEXT, 'CSDN')
- try:
- WebDriverWait(driver,20,0.5).until(EC.presence_of_element_located(locator))
- printdriver.find_element_by_link_text('CSDN').get_attribute('href')
- finally:
- driver.close()
上例中,我们设置了隐性等待和显性等待,在其他操作中,隐性等待起决定性作用,在 WebDriverWait.. 中显性等待起主要作用,但要注意的是:最长的等待时间取决于两者之间的大者,此例中为 20,如果隐性等待时间 > 显性等待时间,则该句代码的最长等待时间等于隐性等待时间。
看了以上内容基本上很清楚了,调用方法如下:
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
这里需要特别注意的是 until 或 until_not 中的可执行方法 method 参数,很多人传入了 WebElement
对象,如下:
- WebDriverWait(driver, 10).until(driver.find_element_by_id('kw')) # 错误
这是错误的用法,这里的参数一定要是可以调用的,即这个对象一定有 __call__() 方法,否则会抛出异常:
- TypeError:
- 'xxx'
- object
- is
- not
- callable
在这里,你可以用 selenium 提供的 expected_conditions 模块中的各种条件,也可以用 WebElement 的 is_displayed() 、is_enabled()、is_selected() 方法,或者用自己封装的方法都可以,那么接下来我们看一下 selenium 提供的条件有哪些:
expected_conditions
expected_conditions 是 selenium 的一个模块,其中包含一系列可用于判断的条件:
: 判断当前页面的 title 是否精确等于预期
- title_is
: 判断当前页面的 title 是否包含预期字符串
- title_contains
: 判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见
- presence_of_element_located
: 判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于 0
- visibility_of_element_located
: 跟上面的方法做一样的事情,只是上面的方法要传入 locator,这个方法直接传定位到的 element 就好了
- visibility_of
: 判断是否至少有 1 个元素存在于 dom 树中。举个例子,如果页面上有 n 个元素的 class 都是'column-md-3',那么只要有 1 个元素存在,这个方法就返回 True
- presence_of_all_elements_located
: 判断某个元素中的 text 是否 包含 了预期的字符串
- text_to_be_present_in_element
: 判断某个元素中的 value 属性是否 包含 了预期的字符串
- text_to_be_present_in_element_value
: 判断该 frame 是否可以 switch 进去,如果可以的话,返回 True 并且 switch 进去,否则返回 False
- frame_to_be_available_and_switch_to_it
: 判断某个元素中是否不存在于 dom 树或不可见
- invisibility_of_element_located
: 判断某个元素中是否可见并且是 enable 的,这样的话才叫 clickable
- element_to_be_clickable
: 等某个元素从 dom 树中移除,注意,这个方法也是返回 True 或 False
- staleness_of
: 判断某个元素是否被选中了, 一般用在下拉列表
- element_to_be_selected
: 判断某个元素的选中状态是否符合预期
- element_selection_state_to_be
: 跟上面的方法作用一样,只是上面的方法传入定位到的 element,而这个方法传入 locator
- element_located_selection_state_to_be
: 判断页面上是否存在 alert
- alert_is_present
上面是所有 17 个 condition,与 until、until_not 组合能够实现很多判断,如果能自己灵活封装,将会大大提高脚本的稳定性。
以 title_is 为例
- class title_is(object):
- """An expectation for checking the title of a page.
- title is the expected title, which must be an exact match
- returns True if the title matches, false otherwise."""
- def __init__(self, title):
- self.title = title
- def __call__(self, driver):
- return self.title == driver.title
可以看到
实际上是 1 个 class,其
- title_is
方法被定义成是返回 1 个 bool 值。因此,一般的用法就是
- __call__
- # 实例化
- the_instance = title_is('expected')
- # 直接在实例上调用__call__
- the_instance(dr) #return True or False
来源: http://www.bubuko.com/infodetail-2011359.html