selenium等待

通常代码执行的速度⽐页⾯渲染的速度要快,如果避免因为渲染过慢出现的⾃动化误报的问题呢?可以使⽤selenium中提供的三种等待⽅法:

1. 隐式等待(Implicit Wait)

隐式等待适用于全局,它告诉 WebDriver 在查找元素时等待一定的时间,直到元素出现。
如果超时,WebDriver 不会抛出异常,而是返回 NoSuchElementException

适用场景

  • 页面加载速度不稳定,元素可能会晚一点出现。
  • 适合不需要精确等待时间的情况。
from selenium import webdriver

# 设置 Edge 浏览器
driver = webdriver.Edge()

# 设置隐式等待 10 秒
driver.implicitly_wait(10)

# 访问网页
driver.get("https://example.com")

# 查找元素(如果元素未出现,则最多等待 10 秒)
element = driver.find_element("id", "someElement")

# 关闭浏览器
driver.quit()
  • implicitly_wait(10) 适用于 整个 WebDriver 生命周期
  • 只需要设置一次,之后所有 find_element() 调用都会等待。
  • 无法针对特定元素设置不同的等待时间

2. 显式等待(Explicit Wait)

显式等待用于等待某个特定元素出现,在超时时间内不断检查,直到条件满足。
它比隐式等待更精确,可以用于特定的元素。

适用场景

  • 只想等待某个特定元素,而不是所有元素。
  • 需要等待的条件较复杂,例如元素可见、可点击等。
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

# 设置 Edge 浏览器
driver = webdriver.Edge()

# 访问网页
driver.get("https://example.com")

# 等待最多 10 秒,直到元素可见
element = WebDriverWait(driver, 10).until(
    EC.presence_of_element_located((By.ID, "someElement"))
)

# 进行操作
element.click()

# 关闭浏览器
driver.quit()
  • WebDriverWait(driver, 10).until() 只会等待指定元素,不会影响其他查找操作。
  • expected_conditions(简称 EC)提供了很多等待条件,例如:
    • EC.presence_of_element_located():元素存在(但可能不可见)。
    • EC.visibility_of_element_located():元素可见。
    • EC.element_to_be_clickable():元素可点击。

3. 强制等待 & Fluent Wait(流畅等待)

time.sleep()(强制等待,不推荐)

使用 time.sleep() 让程序无条件等待,但它不够智能,会浪费时间。

import time

# 强制等待 5 秒
time.sleep(5)
  • time.sleep()无论元素是否出现都等待完整的时间,容易影响效率。
  • 不推荐在 Selenium 自动化测试中使用,除非是调试代码。

Fluent Wait(流畅等待)

Fluent Wait 允许设置轮询间隔,并在超时前不断尝试查找元素。
适用于元素加载速度不稳定的情况。

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

# 等待最多 10 秒,每隔 0.5 秒检查一次
wait = WebDriverWait(driver, 10, poll_frequency=0.5)

element = wait.until(
    EC.presence_of_element_located((By.ID, "someElement"))
)
  • poll_frequency=0.5 代表 每 0.5 秒检查一次,直到超时。
  • Fluent Wait 适用于需要轮询检查的情况

 完全结论!

  • 一般推荐使用 显式等待(Explicit Wait),因为它更精准、灵活。
  • 隐式等待 适用于整个 WebDriver,但可能导致等待时间过长或冲突。
  • 流畅等待(Fluent Wait) 适用于元素加载时间不确定的情况。
  • time.sleep() 强制等待 仅在调试或临时测试时使用,不建议在正式代码中使用。

既然如此,就来扩展讲讲显示等待

常见等待条件

元素是否存在(presence_of_element_located)

等待元素 出现在 DOM(HTML 结构)中,但不一定可见

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)

element = wait.until(
    EC.presence_of_element_located((By.ID, "someElement"))
)
  • 适用于后台加载元素(如 AJAX 请求加载的内容)。
  • 适用于检查是否有该元素,即使它是 display: none 也会被认为存在。

元素是否可见(visibility_of_element_located)

等待元素 出现在 DOM 中,并且可见(即 display != nonevisibility != hidden)。

element = wait.until(
    EC.visibility_of_element_located((By.ID, "someElement"))
)
  • 需要确保元素可见(用户可以看到),适用于点击、输入等操作。

区别

  • presence_of_element_located 仅检查是否存在,不关心是否可见。
  • visibility_of_element_located 额外检查是否可见

元素是否可点击(element_to_be_clickable)

等待元素 可见并且可点击(即 visibility_of_element_located + enabled = True)。

element = wait.until(
    EC.element_to_be_clickable((By.ID, "someButton"))
)
element.click()
  • 适用于 按钮、链接等可交互元素
  • 确保不会因为元素被遮挡未加载完成导致 element.click() 失败。

元素是否不可见(invisibility_of_element_located)

等待元素消失(即 display: noneDOM 中不存在)。

wait.until(
    EC.invisibility_of_element_located((By.ID, "loadingSpinner"))
)
  • 适用于等待 加载动画(Loading Spinner) 消失后,再继续执行操作。

元素内文本是否更新(text_to_be_present_in_element)

等待某个元素的文本等于或包含特定内容。

wait.until(
    EC.text_to_be_present_in_element((By.ID, "status"), "已完成")
)
  •  适用于页面加载完成后,文字发生变化的情况,比如 "处理中" 变成 "已完成"

检查多个元素是否存在(presence_of_all_elements_located)

等待多个元素都出现在 DOM 中。

elements = wait.until(
    EC.presence_of_all_elements_located((By.CLASS_NAME, "item"))
)
  • 适用于批量加载的列表元素,比如产品列表、评论列表等

切换到新窗口(new_window_is_opened)

等待新窗口打开。

wait.until(EC.new_window_is_opened)
driver.switch_to.window(driver.window_handles[-1])
  • 适用于点击某个链接后,会打开 新窗口/新标签页

切换到 alert 弹窗(alert_is_present)

等待 alert 弹窗出现。

alert = wait.until(EC.alert_is_present())
alert.accept()  # 关闭弹窗
  •  适用于处理 JavaScript alert() 弹窗,或者浏览器的确认框(如删除确认)。

综合示例

等待一个元素可见,并且文本内容变为“已加载完成”,然后点击它:

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.Edge()
driver.get("https://example.com")

wait = WebDriverWait(driver, 10)

# 1. 等待按钮可见并可点击
button = wait.until(EC.element_to_be_clickable((By.ID, "confirmButton")))

# 2. 等待文本变为 "已加载完成"
wait.until(EC.text_to_be_present_in_element((By.ID, "statusText"), "已加载完成"))

# 3. 点击按钮
button.click()

# 关闭浏览器
driver.quit()
  • 推荐使用 WebDriverWait + expected_conditions,避免 time.sleep() 造成等待时间过长。
  • 使用 element_to_be_clickable 代替 presence_of_element_located,确保元素可以操作。
  • 结合多个等待条件,比如:
    wait.until(EC.visibility_of_element_located((By.ID, "someElement")))
    wait.until(EC.text_to_be_present_in_element((By.ID, "someElement"), "目标文本"))
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值