明明功能流程没问题,脚本却总是时过时败,元素定位不到、点击失效、断言结果错乱,这类随机翻车的情况屡见不鲜。而解决这类问题最关键的核心,便是用好等待函数。
如今绝大多数软件页面渲染、接口请求、数据刷新都是异步执行,脚本代码的运行速度,远远快于页面加载、后台数据处理的速度。二者运行节奏不同步,是自动化脚本运行不稳定的根本原因,等待函数就是用来抹平这个时间差的核心利器。
合理运用等待函数
一、强制等待
强制等待是通过time.sleep()方法实现的固定时间等待,无论元素是否加载完成,都必须等待指定的时间。
示例代码:
import time
time.sleep(5) # 固定等待5秒
优点:
- 语法简单,容易上手,非常适合新手入门和临时调试
缺点:
- 时间固定、不灵活,无法根据实际情况动态调整
- 会造成大量时间浪费,降低测试执行效率
- 无法判断等待时长是否合理,只能"盲等"
强制等待相当于A同学约B同学在食堂见面,A同学只等10分钟,即使B同学第3分钟就到了,他们也要等到第10分钟才离开
二、隐式等待
隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执⾏,直到超时没找到元素才会报错。
python
driver.implicitly_wait(10)
示例代码:
python
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.implicitly_wait(10) # 统一设定最大等待时长
driver.get("https://example.com")
# 第一次查找:最多等待10秒
user = driver.find_element(By.ID, "username")
# 第二次查找:同样最多等待10秒
btn = driver.find_element(By.CLASS_NAME, "submit-btn")
driver.quit()
优点:
- 设置一次,全局生效,减少重复代码,每次查找时都会进行隐式等待
- 比强制等待更智能,能在元素出现后立即停止等待
缺点:
- 必须等待页面加载完成才生效,效率提升不明显
- 无法针对特定元素进行等待,只能判断元素是否存在
- 如果找不到元素,不会主动报错,可能掩盖问题
隐式等待如同A同学在食堂等B同学,最多等10分钟,如果B同学第3分钟到了,他们第3分钟就出发去图书馆
三、显式等待
在设置的超时时间内,不断检查条件是否满足;一旦满足,立刻执行后续代码;超时不满足,才抛出异常
python
WebDriverWait(driver, 超时秒数,询问间隔).until(等待条件)
等待条件(functions):涉及到selenium.support.ui.ExpectedConditions包下的ExpectedConditions类
示例代码:
python
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10, 0.5).until(
EC.visibility_of_element_located(
(By.XPATH, '//*[@id="someId"]')),message='元素查找失败')
最多等 10 秒,每0.5秒看一眼条件满足没。
如果没找到就报异常
TimeoutException: 元素查找失败
EC 常用条件
python
# 等待元素可见
EC.visibility_of_element_located((By.ID, "id"))
# 等待元素可点击
EC.element_to_be_clickable((By.ID, "id"))
# 等待元素消失
EC.invisibility_of_element((By.XPATH, "xpath"))
# 等待元素存在
EC.presence_of_element_located((By.ID, "id"))
# 等待文本出现在元素中
EC.text_to_be_present_in_element((By.ID, "id"), "提交成功")
优点:
- 专门针对指定元素进行等待,效率最高
- 支持多种预期条件,灵活性极强
- 超时后会抛出明确的
TimeoutException,便于调试和定位问题
缺点:
- 代码较长,实现相对复杂
- 每次使用都需要重新定义,单次有效
显式等待如同A同学每隔一段时间到食堂门口观察B同学是否到了,一旦B同学第3分钟出现,他们立刻出发去图书馆,
四、三类等待的核心区别总结
|----------|----------|----------------|--------------------|
| 对比维度 | 强制等待 | 隐式等待 | 显式等待 |
| 作用范围 | 单次生效 | 全局生效,适用于所有元素查找 | 局部生效,针对特定元素/条件 |
| 等待条件 | 固定时间 | 元素存在于DOM中 | 可自定义多种条件 |
| 实现机制 | 线程休眠 | 轮询查找元素 | 轮询检查指定条件 |
| 超时处理 | 无异常 | 按原错误报错 | 抛出TimeoutException |