当页面未加载完成时,元素可能不能获取,可以设置页面等待提高脚本稳定性。
webdriver提供了两种类型的等待:显式等待、隐式等待
一、隐式等待
implicitly_wait()默认参数的单位为秒,本例中设置等待时长为10 秒。首先这10秒并非一个固定的等待时间,它并不影响脚本的执行速 度。其次,它并不针对页面上的某一元素进行等待。当脚本执行到某个元素定位时,如果元素可以定位,则继续执行;如果元素定位不到,则 它将以轮询的方式不断地判断元素是否被定位到。假设在第6秒定位到 了元素则继续执行,若直到超出设置时长(10秒)还没有定位到元素,则抛出异常
对整个driver周期起作用,只需要在最开始设置一次。
二、sleep方式休眠
三、显式等待
显式等待使WebdDriver等待某个条件成立时继续执行,否则在达到 最大时长时抛弃超时异常(TimeoutException)。
示例代码:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
element = WebDriverWait(driver, 5, 0.5).until(
EC.presence_of_element_located((By.ID, "kw"))
)
element.send_keys('selenium')
driver.quit()
显式等待说明:
- driver - Instance of WebDriver (Ie, Firefox, Chrome or Remote)---驱动器实例对象
- timeout - Number of seconds before timing out---以秒为单位的超时时间
- poll_frequency - sleep interval between calls
By default, it is 0.5 second.-----检查页面元素的间隔时间,默认0.5秒
- ignored_exceptions - iterable structure of exception classes ignored during calls.
By default, it contains NoSuchElementException only.----在等待期间忽略的异常,默认是NoSuchElementException
WebDriverWait一般和until(method, message='')、notuntil(method, message='')一起配合使用
expected_conditions类提供的预期条件判断方法如下图所示:
方法 | 说明 | 示例 |
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
初始化方法中可以看出,title参数必填; __call__表示对象实例可以调用,参数为driver,返回布尔值 |
from selenium import webdriver
import time
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get('http://baidu.com')
title = EC.title_is("百度一下,你就知道")
res = title(driver)
print(res)
driver.quit()
|
title_contains
|
参考title_is | 参考title_is |
presence_of_element_located | 判断元素是否被加在DOM 树里,并不代表该元素一定 可见 |
element = WebDriverWait(driver, 5, 0.5).until(
EC.presence_of_element_located((By.ID, "kw"))
)
element.send_keys('selenium')
|
visibility_of_element_located | 判断元素是否可见(可见代 表元素非隐藏,并且元素的 宽和高都不等于0) | |
visibility_of | 与上一个方法作用相同,只 是上一个方法参数为定位, 该方法接收的参数为定位后 的元素 | |
presence_of_all_elements_located | 判断是否至少有一个元素存 在于DOM树中。例如,在 个页面中有n个元素的class 为“wp”,那么只要有一个存 在就返回True | |
text_to_be_present_in_element | 判断某个元素中的text是否 包含了预期的字符串 | |
text_to_be_present_in_element_value | 判断某个元素的value属性是 否包含了预期的字符串 | |
frame_to_be_available_and_switch_to_it | 判断该表单是否可以切换进 去,如果可以,返回True并 且switch进去,否则返回 False | |
invisibility_of_element_located | 判断某个元素是否不存在于 DOM树或不可见 | |
element_to_be_clickable | 判断元素是否可见并且是可 以点击的 | |
staleness_of | 等到一个元素从DOM树中 移除 | |
element_to_be_selected | 判断某个元素是否被选中, 一般用在下拉列表 | |
element_selection_state_to_be | 判断某个元素的选中状态是 否符合预期 | |
element_located_selection_state_to_be | 与上一个方法作用相同,只 是上一个方法参数为定位后 的元素,该方法接收的参数 为定位 | |
alert_is_present | 判断页面上是否存在alert |