#判断当前页面的title是否精确等于预期,返回布尔值
WebDriverWait(driver,10).until(EC.title_is("百度一下,你就知道"))
#判断当前页面的title是否包含预期字符串,返回布尔值
WebDriverWait(driver,10).until(EC.title_contains('new'))
#判断当前页面的url是否精确等于预期,返回布尔值
WebDriverWait(driver,10).until(EC.url_contains('https://www.baidu.com'))
#判断当前页面的url是否包含预期字符串,返回布尔值
WebDriverWait(driver,10).until(EC.url_contains('baidu'))
#判断当前页面的url是否满足字符串正则表达式匹配,返回布尔值
WebDriverWait(driver,10).until(EC.url_matches('.+baidu.+'))
#判断元素是否出现,只要有一个元素出现,返回元素对象
WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
#判断元素是否可见,返回元素对象
WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(By.ID,'kw')))
#判断元素是否包含指定文本,返回布尔值
WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.NAME,'tj_trnews'),'新闻'))
#判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去
WebDriverWait(driver,10,).until(EC.frame_to_be_available_and_switch_to_it(By.xpath,'//iframe'))
#判断某个元素是否可见并且是可点击的,如果是的就返回这个元素,否则返回False
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.NAME,'tj_trnews')))
#判断某个元素是否被选中,一般用在下拉列表
WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.xpath,'//input[@type="checkbox"]')))
#判断页面上是否存在alert,如果有就切换到alert并返回alert的内容
WebDriverWait(driver,10).until(EC.alert_is_present())
 

按使用场景将 EC 条件分为 6 大类,覆盖 99% 的实战场景:

1. 元素存在 / 可见类(最基础)

表格

条件名 作用 示例
presence_of_element_located(locator) 元素存在于 DOM 中(不要求可见 / 可点击) EC.presence_of_element_located((By.ID, "kw"))
presence_of_all_elements_located(locator) 所有匹配的元素都存在于 DOM 中(返回元素列表) EC.presence_of_all_elements_located((By.TAG_NAME, "a"))
visibility_of_element_located(locator) 元素可见(存在 + 非隐藏 + 尺寸 > 0) EC.visibility_of_element_located((By.ID, "su"))
visibility_of(element) 传入已找到的元素,判断其是否可见 elem = driver.find_element(By.ID, "kw")EC.visibility_of(elem)
invisibility_of_element_located(locator) 元素不可见不存在(用于等待弹窗关闭 / 元素消失) EC.invisibility_of_element_located((By.ID, "popup"))
实战示例:等待元素可见

python

运行

from selenium import webdriver

driver = webdriver.Chrome()
driver.get("https://www.baidu.com")
wait = WebDriverWait(driver, 10)

# 等待搜索框可见(可见后才能输入)
search_box = wait.until(
    EC.visibility_of_element_located((By.ID, "kw"))
)
search_box.send_keys("EC 可见性判断")

2. 元素可交互类(最常用)

表格

条件名 作用 示例
element_to_be_clickable(locator) 元素可点击(可见 + 启用状态,如按钮未禁用) EC.element_to_be_clickable((By.ID, "su"))
element_to_be_selected(locator) 元素被选中(适用于复选框、单选框、下拉选项) EC.element_to_be_selected((By.ID, "checkbox1"))
element_located_to_be_selected(locator) 等同于 element_to_be_selected(参数一致) 同上
element_selection_state_to_be(element, is_selected) 判断元素是否处于指定选中状态 elem = driver.find_element(By.ID, "checkbox1")EC.element_selection_state_to_be(elem, True)
实战示例:等待按钮可点击

python

运行

# 等待百度搜索按钮可点击并点击
search_btn = wait.until(
    EC.element_to_be_clickable((By.ID, "su"))
)
search_btn.click()

3. 文本 / 属性类(判断元素内容)

表格

条件名 作用 示例
text_to_be_present_in_element(locator, text_) 元素包含指定文本(模糊匹配) EC.text_to_be_present_in_element((By.TAG_NAME, "title"), "百度搜索")
text_to_be_present_in_element_value(locator, text_) 元素的 value 属性包含指定文本(适用于输入框) EC.text_to_be_present_in_element_value((By.ID, "kw"), "EC 教程")
attribute_to_be_present_in_element(locator, attr_name) 元素包含指定属性 EC.attribute_to_be_present_in_element((By.ID, "kw"), "name")
element_attribute_to_include(locator, attr, value) 元素的指定属性包含指定值(Selenium 4+) EC.element_attribute_to_include((By.ID, "kw"), "name", "wd")
实战示例:等待页面标题包含指定文本

python

运行

# 等待搜索结果页面标题包含「EC 教程」
wait.until(
    EC.text_to_be_present_in_element((By.TAG_NAME, "title"), "EC 教程_百度搜索")
)

4. 窗口 / 框架类(处理多窗口 /iframe)

表格

条件名 作用 示例
frame_to_be_available_and_switch_to_it(locator) iframe 可用并自动切换到该 iframe EC.frame_to_be_available_and_switch_to_it((By.ID, "iframe1"))
number_of_windows_to_be(num_windows) 浏览器窗口数量等于指定值(适用于新窗口打开) EC.number_of_windows_to_be(2)
new_window_is_opened(current_handles) 检测新窗口是否打开(传入当前窗口句柄列表) handles = driver.window_handlesEC.new_window_is_opened(handles)
实战示例:切换到 iframe

python

运行

# 等待 iframe 加载完成并切换
wait.until(
    EC.frame_to_be_available_and_switch_to_it((By.NAME, "iframe_content"))
)
# 操作 iframe 内的元素
inner_elem = driver.find_element(By.ID, "inner_btn")

5. URL / 标题类(全局页面判断)

表格

条件名 作用 示例
title_is(title) 页面标题完全等于指定值(精确匹配) EC.title_is("EC 教程_百度搜索")
title_contains(text) 页面标题包含指定值(模糊匹配) EC.title_contains("EC 教程")
url_contains(text) URL 包含指定文本 EC.url_contains("baidu.com/s?wd=EC")
url_matches(pattern) URL 匹配正则表达式 EC.url_matches(r"^https://www.baidu.com/s\?wd=.*")
url_to_be(url) URL 完全等于指定值(精确匹配) EC.url_to_be("https://www.baidu.com/s?wd=EC%E6%95%99%E7%A8%8B")
实战示例:等待 URL 包含指定内容

python

运行

# 等待搜索结果 URL 包含关键词
wait.until(
    EC.url_contains("EC%E6%95%99%E7%A8%8B")  # 中文 URL 编码后的值
)

6. 其他实用条件

表格

条件名 作用 示例
alert_is_present() 检测弹窗(alert/confirm/prompt)是否出现 EC.alert_is_present()
staleness_of(element) 元素不再依附于 DOM(适用于等待元素刷新) old_elem = driver.find_element(By.ID, "refresh_elem")EC.staleness_of(old_elem)
实战示例:处理弹窗

python

运行

# 等待弹窗出现并接受
alert = wait.until(EC.alert_is_present())
alert.accept()

三、自定义 EC 条件(扩展内置功能)

如果内置条件无法满足需求,可自定义「条件函数」,格式要求:

  • 函数参数必须包含 driver(WebDriver 实例);
  • 满足条件返回 True/ 目标元素,不满足返回 False

示例 1:判断元素文本长度大于指定值

python

运行

# 自定义条件:元素文本长度 > 10
def text_length_gt_10(driver):
    elem = driver.find_element(By.XPATH, '//div[@id="content_left"]/div[1]//h3/a')
    return len(elem.text) > 10 if elem else False

# 使用自定义条件
wait.until(text_length_gt_10)

示例 2:判断元素样式包含指定值

python

运行

# 自定义条件:元素背景色为红色
def element_bg_is_red(driver):
    elem = driver.find_element(By.ID, "warning_btn")
    bg_color = elem.value_of_css_property("background-color")
    return bg_color == "rgb(255, 0, 0)"  # 红色的 RGB 值

# 等待元素变红
wait.until(element_bg_is_red)

四、实战避坑指南

1. 定位符格式错误

❌ 错误:直接传字符串,而非元组

python

运行

# 错误示例
wait.until(EC.element_to_be_clickable("su"))  # 缺少 (By.ID, ...)

✅ 正确:传入 (By.定位方式, 定位值) 元组

python

运行

wait.until(EC.element_to_be_clickable((By.ID, "su")))

2. 混淆「元素定位」和「元素对象」

部分 EC 条件(如 visibility_of)要求传入已找到的元素对象,而非定位符:

python

运行

# 正确用法
elem = driver.find_element(By.ID, "kw")
wait.until(EC.visibility_of(elem))

# 错误用法(会抛异常)
wait.until(EC.visibility_of((By.ID, "kw")))

3. 超时异常处理

所有 EC 条件超时都会抛出 TimeoutException,必须捕获并处理:

python

运行

from selenium.common.exceptions import TimeoutException

try:
    elem = wait.until(EC.element_to_be_clickable((By.ID, "su")))
except TimeoutException:
    print("等待超时:元素不可点击")
    driver.save_screenshot("timeout_error.png")  # 保存截图排查问题

4. 避免过度等待

  • 优先用「精准条件」(如 element_to_be_clickable),而非「宽泛条件」(如 presence_of_element_located);
  • 合理设置等待时长(如普通场景 5-10 秒,文件下载 30 秒),不要设成 60 秒 +。

五、完整实战脚本(综合使用 EC)

python

运行

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
from selenium.common.exceptions import TimeoutException

def test_ec_functions():
    driver = webdriver.Chrome()
    driver.maximize_window()
    wait = WebDriverWait(driver, 10)

    try:
        # 1. 访问百度
        driver.get("https://www.baidu.com")
        
        # 2. 等待搜索框可点击并输入
        search_box = wait.until(
            EC.element_to_be_clickable((By.ID, "kw"))
        )
        search_box.send_keys("Selenium EC 条件")
        
        # 3. 等待搜索按钮可见并点击
        search_btn = wait.until(
            EC.visibility_of_element_located((By.ID, "su"))
        )
        search_btn.click()
        
        # 4. 等待页面标题包含关键词
        wait.until(
            EC.title_contains("Selenium EC 条件_百度搜索")
        )
        
        # 5. 等待第一个搜索结果可见并打印文本
        first_result = wait.until(
            EC.visibility_of_element_located((By.XPATH, '//div[@id="content_left"]/div[1]//h3/a'))
        )
        print(f"第一个结果:{first_result.text}")
        
        # 6. 等待 URL 包含关键词
        wait.until(
            EC.url_contains("Selenium+EC+条件")
        )
        print(f"当前 URL:{driver.current_url}")

    except TimeoutException as e:
        print(f"执行超时:{e}")
        driver.save_screenshot("ec_error.png")
    finally:
        driver.quit()

if __name__ == "__main__":
    test_ec_functions()

总结

  1. 核心用法:EC 条件需配合 WebDriverWait 使用,传入 (By.定位方式, 定位值) 元组(部分条件需传入元素对象);
  2. 高频条件element_to_be_clickable(可点击)、visibility_of_element_located(可见)、text_to_be_present_in_element(包含文本)是实战中最常用的 3 个条件;
  3. 扩展技巧:内置条件不满足时,可自定义条件函数,只需保证参数包含 driver 且返回布尔值 / 元素。
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐