本文内容参考:https://selenium-python.readthedocs.io/waits.html
为什么要使用等待?
现在大部分网页都是用AJAX技术,但一个网页被浏览器加载后,其中的元素可能会在不同的时间间隔被加载。这样使得定外元素变得困难,因为元素不是一次性全部加载出来的。这样的话,如果元素没有在当前的DOM中出现,定位元素的时候就会返回ElementNotVisibleException。这种情况下,使用等待可以解决这个问题。
都有什么等待方式?
Selenium 提供两种方式的等待: 显式等待和隐式等待。
显式等待是指要满足特定情况才会进行一步。
隐式等待是指让浏览器等待一定的时间后再去定位元素。
怎么用?
显式等待
显示等待其实就是满足某一特定的情况下才进行一步。粗暴用法,或者说简单的用法就是 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()
这样的话,10秒之内如果找到元素的话就返回元素,10秒后还没有找到元素的则会返回TimeoutException. 默认的话WebDriverWait每500毫秒就会去执行一遍ExpectedCondition。
Expected Conditions
selenium 中一些常用的conditions如下:
- 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')))
隐式等待
隐式等待是让浏览器在寻找不是立即可得的元素时在一定时间内去搜索DOM.如下面例子:
from selenium import webdriverdriver = webdriver.Firefox() driver.implicitly_wait(10) # seconds driver.get("http://somedomain/url_that_delays_loading") myDynamicElement = driver.find_element_by_id("myDynamicElement")