Selenium 对于 UI 自动化,就像是内功对于 “古典武学”,招式可以变(Cypress/Playwright),但内功(WebDriver 协议)是通用的。
尽管对于 AI 而言更青睐 Playwright 与 AgentBrowser,这让 Selenium 在 AI 时代略显尴尬,但作为历经多年沉淀的技术,其庞大的应用体量仍能让我们借此感受浏览器自动化的魅力。而且对于部分公司的 UI 自动化测试平台而言,Selenium 已运行稳定,因此它依旧占据一席之地,掌握它对于我们测试人员而言,堪称技术基石。
忘掉手动下载 chromedriver.exe 的上古做法。2026 年的标准实践强调自动化管理与环境隔离。
你的 Python/Java 代码,通过 W3C WebDriver 协议发送 JSON 指令。
Selenium 4 彻底废弃 JSON Wire Protocol,全面拥抱 W3C。ChromeDriver 等作为独立服务运行,与浏览器通过 HTTP/JSON 通信,响应更稳定。
真正的执行端。
Python 3.9+ (推荐 3.10/3.11),使用 venv 创建隔离环境,避免包冲突。
pip install selenium
webdriver-manager 库。它能自动检测本地浏览器版本并下载匹配驱动。
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
from webdriver_manager.chrome import ChromeDriverManager
service = ChromeService(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
在大多数公网环境下,这能显著改善驱动匹配问题。但在企业内网或特殊定制浏览器环境中,可能需要配置代理或手动指定镜像源。
Selenium Manager CLI。如果 webdriver-manager 失效,新版 Selenium 自带的 SeleniumManager 会尝试自动下载驱动,无需代码引入第三方库。
在严格的离线环境中,需将驱动二进制文件放入系统 PATH,或通过 Docker 镜像固化环境。
1.ID / Name:唯一且通常不随样式改变。
username_input = driver.find_element(By.ID, "user-login-id")
2.CSS Selector:企业级首选。速度快、语法简洁、浏览器原生支持好。
推荐:#id, .class, input[name='phone'], div > p (父子关系)。
phone_input = driver.find_element(By.CSS_SELECTOR, "input[name='phone']")
3.XPath:最后手段。功能最强但速度慢、可读性差。严禁使用绝对路径(如 /html/body/div[1]...)。仅在需要跨越 iframe 或根据文本内容查找时使用。
submit_btn = driver.find_element(By.XPATH, "//button[text()='立即登录']")
4.Selenium 4 革命性特性:相对定位器 (Relative Locators):当前必须掌握。基于元素间的视觉关系(上下左右、邻近)定位,极大提升健壮性。
from selenium.webdriver.support.locators import with_tag_name
from selenium.webdriver.support.relative_locator import locate_with
# 找到 "password" 输入框下方的 "submit" 按钮
password_field = driver.find_element(By.ID, "password")
submit_button = driver.find_element(locate_with(By.TAG_NAME, "button").below(password_field))
行业铁律:永远、永远不要使用 time.sleep()! 这会导致测试时间不可控,且在 CI/CD 中极不可靠。
作为基础保障,设置一次即可(通常 5-10 秒),用于应对网络延迟。
driver.implicitly_wait(10)
针对特定元素、特定状态进行精准等待。
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# 等待按钮变为“可点击”状态,最长等待10秒
submit_btn = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "submit-btn"))
)
submit_btn.click()
这是从 “写脚本” 到 “做框架” 的分水岭。
project/
├── pages/ # 页面对象层
│ ├── base_page.py # 封装通用方法 (find, click, wait)
│ └── login_page.py # 登录页元素与操作
├── tests/ # 测试用例层 (只关心业务)
│ └── test_login.py
├── data/ # 测试数据分离
│ └── login_data.yaml
└── conftest.py # Pytest Fixture (管理 driver 生命周期)
from selenium.webdriver.common.by import By
from .base_page import BasePage
class LoginPage(BasePage):
# 元素定位器私有化
_username_input = (By.ID, "username")
_password_input = (By.ID, "password")
_submit_btn = (By.CSS_SELECTOR, "button[type='submit']")
def enter_username(self, username):
self.find_element(self._username_input).send_keys(username)
def enter_password(self, password):
self.find_element(self._password_input).send_keys(password)
def click_submit(self):
self.find_element(self._submit_btn).click()
# 业务操作封装
def login(self, username, password):
self.enter_username(username)
self.enter_password(password)
self.click_submit()
# 返回下一个页面的对象 (链式调用)
from .home_page import HomePage
return HomePage(self.driver)
回忆起上一家公司,笔者就参与到了 UI 自动化平台的搭建,也是使用的 Selenium,所以不言而喻 Selenium 是笔者的白月光。即使是后来接触到了 Playwright,以及 AgentBrowser,情感依旧是抵不过 Selenium,毕竟前两者技术在笔者看来发展的逐渐趋势是对 AI 友好,而后者依旧是对人类友好。