等待某个条件成立,然后对这个条件进行验证。

(图片来源网络,侵删)
我们将从以下几个层面来解析“判断”:
- 等待元素出现(最核心的判断)
- 判断元素是否存在
- 判断元素的状态(可见、可点击、选中、禁用等)
- 判断元素的属性和文本内容
- 判断弹窗(Alert)是否存在
- 判断 JavaScript 返回值
等待元素出现(最核心的判断)
这是最重要、最常用的一种判断,直接使用 find_element 方法,如果元素不存在,会立即抛出 NoSuchElementException 异常,导致脚本中断,为了避免这种情况,我们必须使用“等待”。
Selenium 提供了两种等待方式:
a) 隐式等待
- 作用:在整个生命周期内(从
driver.get()后到driver.quit()前),对所有find_element或find_elements调用设置一个全局的超时时间。 - 工作原理:它不会让脚本立即停止,而是会不断地尝试查找元素,直到元素被找到或者超时时间到达。
- 缺点:不够灵活,它只关心元素是否存在,不关心元素是否可见、可点击等,如果第一个元素 5 秒后出现,第二个元素 1 秒后出现,它仍然会等待 5 秒。
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
driver = webdriver.Chrome()
driver.implicitly_wait(10) # 设置隐式等待,最长等待10秒
driver.get("https://www.example.com")
try:
# 如果元素在10秒内出现,代码会继续执行
# 如果10秒后仍未出现,会抛出 NoSuchElementException
element = driver.find_element("id", "some_dynamic_id")
print("元素找到了!")
except NoSuchElementException:
print("在10秒内未找到元素。")
driver.quit()
b) 显式等待 (强烈推荐)
- 作用:为特定的元素设置一个明确的等待条件,直到该条件满足或超时。
- 工作原理:它会每隔一段时间(默认0.5秒)检查一次条件,一旦条件满足,立即继续执行代码,效率更高。
- 优点:非常灵活和精确,可以等待元素可见、可点击、文本包含特定内容等任意条件。
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
driver = webdriver.Chrome()
driver.get("https://www.example.com")
try:
# 等待最多10秒,直到ID为 "some_dynamic_id" 的元素可见
# WebDriverWait(driver, timeout).until(条件)
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "some_dynamic_id"))
)
print("元素可见了!")
# 你也可以链式判断,比如等待元素出现并可点击
clickable_element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "button.submit"))
)
clickable_element.click()
except TimeoutException:
print("在10秒内,元素未变为可见或可点击。")
driver.quit()
常用的 expected_conditions (EC) 条件:

(图片来源网络,侵删)
| 条件 | 说明 | 示例 |
|---|---|---|
visibility_of_element_located |
元素可见(不仅存在于DOM中,而且display, visibility, opacity等属性不为隐藏) | EC.visibility_of_element_located((By.ID, "myId")) |
presence_of_element_located |
元素存在于DOM中(不一定可见) | EC.presence_of_element_located((By.XPATH, "//div")) |
element_to_be_clickable |
元素可见且可点击 | EC.element_to_be_clickable((By.CSS_SELECTOR, "button")) |
invisibility_of_element_located |
元素不可见或不存在于DOM中 | EC.invisibility_of_element_located((By.ID, "loading-spinner")) |
text_to_be_present_in_element |
元素的文本包含特定字符串 | EC.text_to_be_present_in_element((By.TAG_NAME, "h1"), "Welcome") |
alert_is_present |
页面上存在弹窗 | EC.alert_is_present() |
判断元素是否存在
判断一个元素是否存在,最稳健的方法就是结合 try...except 和 find_elements(注意是 elements,复数形式)。
find_element:找不到元素会抛出NoSuchElementException。find_elements:找不到元素会返回一个空列表[],不会抛出异常。
from selenium import webdriver
def is_element_present(driver, by, value):
"""
判断元素是否存在
:return: True 如果存在, False 如果不存在
"""
elements = driver.find_elements(by, value)
return len(elements) > 0
driver = webdriver.Chrome()
driver.get("https://www.example.com")
# 判断ID为 "non_existent_id" 的元素是否存在
if is_element_present(driver, "id", "non_existent_id"):
print("元素存在")
else:
print("元素不存在")
# 判断 "h1" 标签是否存在
if is_element_present(driver, "tag name", "h1"):
print("h1标签存在")
else:
print("h1标签不存在")
driver.quit()
判断元素的状态
在执行操作(如点击、输入)前,判断元素的状态非常重要。
a) 判断元素是否可见
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.example.com")
element = driver.find_element("tag name", "h1")
# is_displayed() 方法返回布尔值
if element.is_displayed():
print("元素是可见的")
else:
print("元素是不可见的")
driver.quit()
b) 判断元素是否可点击
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.example.com/button_page.html")
button = driver.find_element("id", "myButton")
# is_enabled() 方法判断元素是否被禁用
if button.is_enabled():
print("按钮是可用的(未被禁用)")
else:
print("按钮是不可用的(已被禁用)")
# is_enabled() + is_displayed() 通常用来判断是否可点击
if button.is_enabled() and button.is_displayed():
print("按钮是可见且可点击的")
button.click()
else:
print("按钮不可点击")
driver.quit()
c) 判断复选框或单选框是否被选中
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.example.com/checkbox.html")
checkbox = driver.find_element("id", "agree_terms")
# is_selected() 方法返回布尔值
if checkbox.is_selected():
print("复选框已被选中")
else:
print("复选框未被选中")
# 选中它
checkbox.click()
# 再次判断
if checkbox.is_selected():
print("复选框现在已被选中")
else:
print("复选框仍未被选中")
driver.quit()
判断元素的属性和文本内容
a) 判断文本内容
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.example.com")
h1_text = driver.find_element("tag name", "h1").text
if "Example Domain" in h1_text:
print("页面标题文本正确")
else:
print(f"页面标题文本不正确,实际为: {h1_text}")
driver.quit()
b) 判断属性值
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.example.com")
# 获取元素的 'href' 属性
link = driver.find_element("tag name", "a")
href_value = link.get_attribute("href")
if href_value == "https://www.iana.org/domains/example":
print("链接的 'href' 属性值正确")
else:
print(f"链接的 'href' 属性值不正确,实际为: {href_value}")
# 判断元素是否有某个属性
if link.get_attribute("target"):
print("该链接有 'target' 属性")
else:
print("该链接没有 'target' 属性")
driver.quit()
判断弹窗是否存在
判断弹窗通常和显式等待结合使用。
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
driver = webdriver.Chrome()
driver.get("https://www.example.com") # 假设这个页面会弹出Alert
try:
# 等待最多10秒,直到Alert出现
WebDriverWait(driver, 10).until(EC.alert_is_present())
print("Alert 弹窗已出现")
# 切换到Alert
alert = driver.switch_to.alert
# 获取Alert文本
alert_text = alert.text
print(f"Alert的文本是: {alert_text}")
# 接受Alert
alert.accept()
print("已接受Alert")
except TimeoutException:
print("在10秒内未出现Alert弹窗。")
driver.quit()
总结与最佳实践
| 判断场景 | 推荐方法 | 说明 |
|---|---|---|
| 等待元素出现或满足条件 | 显式等待 | 这是最重要的技巧,用于处理动态加载的网页,使脚本更稳定、高效。 |
| 判断元素是否存在 | find_elements + len() > 0 |
避免使用 try...except,因为复数形式的 find_elements 更优雅。 |
| 判断元素是否可见 | element.is_displayed() |
用于确认元素是否对用户可见。 |
| 判断元素是否可操作 | element.is_enabled() |
用于判断输入框、按钮等是否被禁用。 |
| 判断复选框/单选框状态 | element.is_selected() |
用于判断是否被勾选。 |
| 判断文本/属性内容 | element.text / element.get_attribute() |
用于验证页面内容是否符合预期。 |
| 判断弹窗 | WebDriverWait + EC.alert_is_present() |
用于处理需要用户交互的弹窗。 |
核心思想:永远不要让你的脚本“裸奔”(即不加判断地直接操作元素),始终使用等待和断言来确保操作的对象已经准备好,从而构建出健壮、可靠的自动化测试脚本。

(图片来源网络,侵删)
