現在,大多數網絡應用都使用AJAX技術。當瀏覽器加載頁面時,該頁面中的元素可能會以不同的時間間隔加載。這使得定位元素變得困難:如果元素還沒有出現在DOM中,則定位函數將引發ElementNotVisibleException異常。使用等待,我們可以解決這個問題。
Selenium Webdriver提供了兩種類型的等待 - 隱式和顯式。明確的等待使得WebDriver在繼續執行之前等待一定的條件發生。隱式等待使WebDriver在嘗試查找元素時輪詢DOM一段時間。
顯式等待
明確代碼等待時間,以便在繼續執行代碼之前等待某種條件發生。這種情況的極端是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 driver = webdriver.Chrome() driver.get("http://www.baidu.com") try: element = WebDriverWait(driver, 10).until( expected_conditions.presence_of_element_located((By.LINK_TEXT, "hao123")) ) finally: driver.quit()
10秒之後拋出TimeoutException。WebDriverWait默認每500毫秒調用一次ExpectedCondition,直到它成功返回。ExpectedCondition的返回類型是布爾值,返回true或非null返回值。
預期條件
expected_conditions模塊包含一組與WebDriverWait一起使用的預定義條件。expected_condition類常用預期條件。下面列出每個的名稱。你可以直接使用expected_condition類進行調用
alert_is_present
element_located_selection_state_to_be
element_located_to_be_selected
element_selection_state_to_be
element_to_be_clickable
element_to_be_selected
frame_to_be_available_and_switch_to_it
invisibility_of_element_located
new_window_is_opened
number_of_windows_to_be
presence_of_all_elements_located
presence_of_element_located
staleness_of
text_to_be_present_in_element
text_to_be_present_in_element_value
title_contains
title_is
url_changes
url_contains
url_matches
url_to_be
visibility_of
visibility_of_all_elements_located
visibility_of_any_elements_located
visibility_of_element_located
自定義等待條件
你可以創建自定義等待條件。可以使用具有__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"))