等待机制
本教程共 42 篇 · 第 28 篇 · 更新于 2026-07-29 · 约 6 分钟阅读
28. 等待机制
本节目标:理解 DrissionPage 的等待机制,学会用智能等待替代 sleep,提高自动化程序的稳定性和效率。
为什么需要等待
网络环境不稳定,页面 js 运行时间也不确定。自动化过程中经常遇到需要等待的情况。
总是用 sleep() 不太优雅。等待多了浪费时间,等待不够会报错。
DrissionPage 内置了智能等待方法,藏在页面对象和元素对象的 wait 属性里。
所有等待方法都有 timeout 参数。可以设置超时时间,也可以设置超时后返回 False 还是抛出异常。
页面对象的等待方法
页面对象指 ChromiumTab、MixTab 和 ChromiumFrame。
from DrissionPage import Chromium
tab = Chromium().latest_tab
tab.get('http://DrissionPage.cn')
tab.wait.ele_displayed('tag:div')
wait.load_start() — 等待页面开始加载
点击元素跳转到新页面时,用此方法等待页面开始加载。避免在新页面获取到旧页面的元素。
ele.click() # 点击某个元素
tab.wait.load_start() # 等待页面进入加载状态
print(tab.title) # 此时可以安全操作新页面
Note方法已内置等待加载开始,后面不需要跟
wait.load_start()。只有点击跳转等场景才需要。
wait.doc_loaded() — 等待页面文档加载完成
等待页面 DOM 文档加载完成。一般不需要手动使用,程序大部分动作会自动等待。
tab.wait.doc_loaded()
wait.eles_loaded() — 等待元素加载到 DOM
等待指定元素被加载到 DOM 中。可以等待全部或任意一个。
# 等待 id 为 div1 的元素加载
tab.wait.eles_loaded('#div1')
# 等待任意一个加载即返回
tab.wait.eles_loaded(('#div1', '#div2'), any_one=True)
# 设置超时 5 秒
tab.wait.eles_loaded('#div1', timeout=5)
wait.ele_displayed() — 等待元素显示
等待元素从隐藏变成显示状态。如果元素不在 DOM 中,会先等待加载再等待显示。
# 等待元素显示,超时使用页面设置
tab.wait.ele_displayed('#div1')
# 设置超时 3 秒
tab.wait.ele_displayed('#div1', timeout=3)
# 等待已获取到的元素显示
ele = tab.ele('#div1')
tab.wait.ele_displayed(ele)
wait.ele_hidden() — 等待元素隐藏
等待元素从显示变成隐藏状态。
tab.wait.ele_hidden('#loading')
wait.ele_deleted() — 等待元素从 DOM 删除
等待元素被从 DOM 中移除。
tab.wait.ele_deleted('#popup')
wait.url_change() — 等待 URL 变化
等待页面 URL 变成包含或不包含指定文本。适合多重跳转后判断到达目标页面。
# 等待 URL 变成包含指定文本
tab.wait.url_change('https://www.example.com/center/')
# 等待 URL 不包含指定文本
tab.wait.url_change('login', exclude=True)
# 设置超时
tab.wait.url_change('/dashboard', timeout=10)
wait.title_change() — 等待标题变化
等待页面 title 变成包含或不包含指定文本。
tab.wait.title_change('首页')
tab.wait.title_change('登录', exclude=True)
wait.new_tab() — 等待新标签页
等待新标签页出现,返回新标签页的 id。
tab.wait.new_tab()
wait.alert_closed() — 等待弹出框关闭
等待 alert 或 confirm 等弹出框被关闭。
tab.wait.alert_closed()
wait.upload_paths_inputted() — 等待上传路径填入
等待文件上传路径自动填写完成。详见 §24 文件上传章节。
tab.wait.upload_paths_inputted()
元素对象的等待方法
元素对象也有 wait 属性,用于等待自身状态变化。
ele = tab.ele('tag:div')
ele.wait.displayed()
wait.displayed() — 等待元素显示
ele.wait.displayed() # 使用页面默认超时
ele.wait.displayed(timeout=3) # 设置 3 秒超时
wait.hidden() — 等待元素隐藏
ele.wait.hidden()
ele.wait.hidden(timeout=3)
wait.deleted() — 等待元素从 DOM 删除
ele.wait.deleted()
wait.covered() — 等待元素被覆盖
等待元素被其他元素覆盖。
ele.wait.covered()
wait.not_covered() — 等待元素不被覆盖
等待遮挡元素消失。适合等待”加载中”遮罩消失后操作。
ele.wait.not_covered()
wait.enabled() — 等待元素可用
等待元素从 disabled 变成可用状态。
ele.wait.enabled()
wait.disabled() — 等待元素不可用
ele.wait.disabled()
wait.has_rect() — 等待元素拥有大小
等待元素被赋予大小和位置信息。
ele.wait.has_rect()
wait.stop_moving() — 等待元素停止运动
等待元素运动结束。适合动画结束后再操作。
ele.wait.stop_moving()
ele.wait.stop_moving(gap=0.2) # 检测间隔 0.2 秒
wait.clickable() — 等待元素可点击
等待元素变为可点击状态。
ele.wait.clickable()
ele.wait.clickable(wait_moved=True) # 是否等待元素运动结束
wait.disabled_or_deleted() — 等待元素不可用或被删除
ele.wait.disabled_or_deleted()
超时和错误处理
所有等待方法都支持 timeout 和 raise_err 参数。
# 设置超时时间
tab.wait.ele_displayed('#div1', timeout=5)
# 超时后抛出异常(默认根据 Settings 设置)
tab.wait.ele_displayed('#div1', raise_err=True)
# 超时后返回 False
tab.wait.ele_displayed('#div1', raise_err=False)
综合示例:等待加载完成再操作
from DrissionPage import Chromium
tab = Chromium().latest_tab
tab.get('https://example.com')
# 点击按钮触发加载
tab.ele('#load-btn').click()
# 等待加载遮罩消失
tab.wait.ele_hidden('#loading-overlay')
# 等待目标内容显示
tab.wait.ele_displayed('#content')
# 获取内容
print(tab.ele('#content').text)
综合示例:等待跳转完成
# 点击登录
tab.ele('#login-btn').click()
# 等待 URL 跳转到首页
tab.wait.url_change('/home')
# 或者等待标题变化
tab.wait.title_change('首页')
# 继续操作
print(f'当前页面: {tab.title}')
综合示例:等待弹窗消失
# 点击删除按钮
tab.ele('#delete-btn').click()
# 等待确认弹窗出现
tab.wait.ele_displayed('#confirm-dialog')
# 点击确认
tab.ele('#confirm-btn').click()
# 等待弹窗消失
tab.wait.ele_hidden('#confirm-dialog')
# 等待元素从 DOM 删除
tab.wait.ele_deleted('#item-123')
综合示例:等待元素可交互
# 等待按钮停止运动
btn = tab.ele('#submit-btn')
btn.wait.stop_moving()
# 等待按钮不被覆盖
btn.wait.not_covered()
# 等待按钮可用
btn.wait.enabled()
# 现在可以安全点击
btn.click()