为什么要用等待?
页面加载元素需要时间,如果元素还未加载成功就执行脚本,会找不到指定的元素。
三种等待方法
1、强制等待
强制等待,使脚本暂停指定时间。
import time
time.sleep(2)
2、隐式等待
会在每个页面加载时自动等待;只需声明一次,一般在打开浏览器后进行声明。声明之后对整个drvier的生命周期都有效,后面不用重复声明。
会在指定时间内等整个页面加载完成才会执行下一步,但有时元素在页面加载完之前就已经出现了,所以不推荐使用隐式等待,会增加脚本运行时间。
from selenium import webdriver
from chromedriver_py import binary_path # this will get you the path variable
svc = webdriver.ChromeService(executable_path=binary_path)
driver = webdriver.Chrome(service=svc)
driver.implicitly_wait(10)
3、显示等待(推荐使用)
显示等待必须在每个需要等待的元素前面进行声明。会在指定时间内 判断条件是否成立,如果超时条件不成立,会抛出异常。
显示等待中有两个类,WebDriverWait 和 expected_conditions
WebDriverWait 可以设定等待元素加载的时间;它提供了until()
方法,可以指定一个条件,当条件为真或超时时,等待结束。
expected_conditions 提供了一系列用于等待特定条件的方法,用于检查等待时间内元素是否满足某些条件。
使用需要导入两个类
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
常用方法及示例
- title_is
等待页面标题等于指定值。
WebDriverWait(driver, 10).until(EC.title_is("Expected Title"))
- title_contains
等待页面标题包含指定的子字符串。
WebDriverWait(driver, 10).until(EC.title_contains("Partial Title"))
- presence_of_element_located
等待指定元素的存在(在DOM中,但不一定可见)。
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "elementId"))
)
- visibility_of_element_located
等待指定元素可见,可见代表元素非隐藏,并且元素的宽和高都不等于0。
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "elementId"))
)
- visibility_of
等待指定元素可见,与上面方法一样。
element = WebDriverWait(driver, 10).until(
EC.visibility_of(driver.find_element(By.ID, "elementId")))
)
- element_to_be_clickable
等待指定元素可被点击。
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "elementId"))
)
- staleness_of
等待指定元素不再是当前的DOM元素(页面已发生变化)。
element = driver.find_element(By.ID, "elementId")
WebDriverWait(driver, 10).until(EC.staleness_of(element))
- alert_is_present
等待弹出窗口出现。
WebDriverWait(driver, 10).until(EC.alert_is_present())
- frame_to_be_available_and_switch_to_it
等待指定的iframe可用并切换到它。
WebDriverWait(driver, 10).until(
EC.frame_to_be_available_and_switch_to_it((By.NAME, "frameName"))
)
- element_selection_state_to_be
验证某个元素是否被选中或未选中。
element = driver.find_element(By.ID, "checkboxId")
WebDriverWait(driver, 10).until(EC.element_selection_state_to_be(element, True))
- visibility_of_any_elements_located
等待至少一个指定的元素可见。
elements = WebDriverWait(driver, 10).until(
EC.visibility_of_any_elements_located((By.CLASS_NAME, "className"))
)
- text_to_be_present_in_element
等待指定元素的文本内容包含指定文本。
element = WebDriverWait(driver, 10).until(
EC.text_to_be_present_in_element((By.ID, "elementId"), "Expected Text")
)
显示等待,可以自己写条件
实例,指定时间内,等待 打开左侧菜单栏图标 出现, 出现后点击
element = WebDriverWait(driver, 10).until(lambda driver: driver.find_element(By.CSS_SELECTOR,
"svg[xmlns='http://www.w3.org/2000/svg']"))
element.click()