5.等待
目前,大多数Web应用程序都在使用AJAX技术。当浏览器加载页面时,该页面中的元素可能以不同的时间间隔加载。这使定位元素变得困难:如果DOM中尚未存在元素,则locate函数将引发ElementNotVisibleException异常。使用等待,我们可以解决这个问题。等待在执行的操作之间提供了一些松弛 - 主要是使用元素定位元素或任何其他操作。
Selenium Webdriver提供两种类型的等待 - 隐式和显式。显式等待使WebDriver等待某个条件发生,然后再继续执行。在尝试查找元素时,隐式等待会使WebDriver轮询DOM一段时间。
5.1。显式等待
显式等待是您定义的代码,用于在进一步执行代码之前等待某个条件发生。这种情况的极端情况是time.sleep(),它将条件设置为等待的确切时间段。提供了一些便捷方法,可以帮助您编写仅在需要时等待的代码。WebDriverWait与ExpectedCondition相结合是一种可以实现的方法。
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://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
这会在抛出TimeoutException之前等待最多10秒,除非它发现元素在10秒内返回。默认情况下,WebDriverWait每500毫秒调用一次ExpectedCondition,直到它成功返回。对于所有其他ExpectedCondition类型,ExpectedCondition类型的布尔返回true或非null返回值成功返回。
预期条件
在自动化Web浏览器时,常常会出现一些常见情况。下面列出的是每个的名称。Selenium Python绑定提供了一些方便的方法,因此您不必自己编写expected_condition类或为它们创建自己的实用程序包。
.title_is
.title_contains
.presence_of_element_located
.visibility_of_element_located
.visibility_of
.presence_of_all_elements_located
.text_to_be_present_in_element
.text_to_be_present_in_element_value
.frame_to_be_available_and_switch_to_it
.invisibility_of_element_located
.element_to_be_clickable
.staleness_of
.element_to_be_selected
.element_located_to_be_selected
.element_selection_state_to_be
.element_located_selection_state_to_be
.alert_is_present
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
expected_conditions模块包含一组用于WebDriverWait的预定义条件。
自定义等待条件
如果以前的便捷方法都不符合您的要求,您还可以创建自定义等待条件。可以使用带有__call__方法的类创建自定义等待条件,该方法在条件不匹配时返回False。
class element_has_css_class(object):
"""An expectation for checking that an element has a particular css class.
locator - used to find the element
returns the WebElement once it has the particular css class
"""
def __init__(self, locator, css_class):
self.locator = locator
self.css_class = css_class
def __call__(self, driver):
element = driver.find_element(*self.locator) # Finding the referenced element
if self.css_class in element.get_attribute("class"):
return element
else:
return False
# Wait until an element with id='myNewInput' has class 'myCSSClass'
wait = WebDriverWait(driver, 10)
element = wait.until(element_has_css_class((By.ID, 'myNewInput'), "myCSSClass"))
5.2。隐式等待
隐式等待告诉WebDriver在尝试查找不能立即可用的任何元素(或元素)时轮询DOM一段时间。默认设置为0.设置后,将为WebDriver对象的生命周期设置隐式等待。
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(10) # seconds
driver.get("http://somedomain/url_that_delays_loading")
myDynamicElement = driver.find_element_by_id("myDynamicElement")