每次手动点击网页按钮时,你有没有想过让程序自动完成这些重复操作?去年我接手一个电商项目,每天要手动测试30多个页面的优惠券功能,直到发现Selenium这个神器。它就像个不知疲倦的机器人,能24小时自动帮你点击、输入、验证页面,特别适合下面这些场景:
但要注意,不是所有情况都适合自动化。上周有个团队想用Selenium测试频繁改版的首页,结果每天都要重写脚本,这就是典型的反面案例。最适合的场景是核心业务流程(如支付、登录)和长期稳定的功能模块。
新手最怕环境配置,我用Windows/Mac双系统实测的这个方案成功率最高:
bash复制# 1. 安装Python(推荐3.8+版本)
brew install python # Mac
choco install python # Windows用Chocolatey
# 2. 安装Selenium库
pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple
# 3. 下载浏览器驱动(重点!)
# Chrome驱动地址:https://chromedriver.chromium.org/downloads
# 版本必须与本地浏览器完全一致!
这里有个血泪教训:去年帮客户调试时发现脚本死活不运行,最后发现是Chrome自动更新后版本不匹配。驱动版本必须精确到小数点后两位,比如Chrome 115.0.5790.110对应的驱动必须是115.0.5790.x。
建议把驱动文件放在项目根目录下,然后这样初始化:
python复制from selenium import webdriver
driver = webdriver.Chrome(executable_path="./chromedriver") # 相对路径更便携
Edge浏览器现在内置了Selenium IDE插件,就像录屏软件一样简单:
但录制生成的代码就像方便面——能应急但不健康。我见过最离谱的案例是生成了300行包含绝对XPath的脚本,页面改个按钮位置就全废了。
这个搜索百度的例子藏着几个关键技巧:
python复制from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
driver.get("https://www.baidu.com")
# 更健壮的定位方式(CSS选择器优先于XPath)
search_box = driver.find_element(By.CSS_SELECTOR, "#kw")
search_box.send_keys("selenium")
# 显式等待比sleep更智能
submit_btn = WebDriverWait(driver, 10).until(
lambda x: x.find_element(By.ID, "su")
)
submit_btn.click()
实际项目中我会用Page Object模式把元素定位和业务逻辑分离,比如:
python复制class BaiduPage:
def __init__(self, driver):
self.driver = driver
self.search_input = (By.ID, "kw")
def search(self, keyword):
self.driver.find_element(*self.search_input).send_keys(keyword)
直接上我优化过的项目目录结构:
code复制├── config/
│ ├── browser_config.py # 浏览器参数配置
├── pages/ # 页面对象类
│ ├── login_page.py
├── tests/
│ ├── test_login.py # 测试用例
├── conftest.py # Pytest夹具配置
└── requirements.txt
关键配置示例(conftest.py):
python复制import pytest
from selenium import webdriver
@pytest.fixture(scope="module")
def browser():
driver = webdriver.Chrome()
driver.implicitly_wait(5) # 全局隐式等待
yield driver
driver.quit() # 测试结束后自动关闭
这个装饰器能帮你在用例失败时保存现场:
python复制def screenshot_on_failure(func):
def wrapper(browser, *args, **kwargs):
try:
return func(browser, *args, **kwargs)
except Exception as e:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
browser.save_screenshot(f"fail_{timestamp}.png")
raise
return wrapper
用Selenium Grid实现一套脚本多浏览器运行:
python复制# browser_config.py
BROWSERS = {
"chrome": {
"command_executor": "http://192.168.1.100:4444/wd/hub",
"options": webdriver.ChromeOptions()
},
"firefox": {
"command_executor": "http://192.168.1.100:4444/wd/hub",
"options": webdriver.FirefoxOptions()
}
}
启动Grid服务端(需要Docker环境):
bash复制docker run -d -p 4444:4444 --shm-size="2g" selenium/hub
docker run -d -p 5900:5900 --shm-size="2g" selenium/node-chrome
按优先级使用定位策略:
time.sleep(5) (最后的选择)driver.implicitly_wait(10) (全局设置)python复制from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "submit"))
)
[id^="button-"]driver.switch_to.frame("frame_name")element.send_keys("/path/to/file")最近在金融项目中发现个隐蔽问题:Chrome的自动填充功能会遮挡表单元素,解决方法是在测试时禁用自动填充:
python复制options = webdriver.ChromeOptions()
options.add_experimental_option("prefs", {
"profile.password_manager_enabled": False,
"credentials_enable_service": False
})
建议把常用操作封装成工具函数,比如这个清理浏览器缓存的函数:
python复制def clear_cache(driver):
driver.execute_cdp_cmd("Network.clearBrowserCache", {})
driver.get("chrome://settings/clearBrowserData")
# 模拟点击清除按钮...