Selenium + Python:浏览器自动化测试从入门到实战
Introduction
想自动化测试一个网站:打开浏览器、点击按钮、填写表单、验证结果——这些手动操作能自动化吗?当然能!Selenium 是业界最成熟的 Web 自动化工具,支持 Chrome、Firefox、Safari、Edge。
本文用 Python + Selenium,从安装到实战完整走一遍,最后集成到 pytest 框架。
---
基础语法
1. 安装
pip install selenium webdriver-manager pytest pytest-selenium
webdriver-manager 自动下载并管理浏览器驱动,不用手动配置。
2. 第一个 Selenium 测试
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 启动 Chrome(headless 模式)
options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://shaoda.net")
print(driver.title) # 打印页面标题
# 查找搜索框并输入内容
search_box = driver.find_element(By.NAME, "q")
search_box.send_keys("Python")
search_box.send_keys(Keys.RETURN)
# 等待搜索结果加载
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CLASS_NAME, "results"))
)
# 验证结果
assert "Python" in driver.page_source
print("测试通过!")
finally:
driver.quit()
3. 常用元素定位方式
| 定位方式 | 代码 | 适用场景 |
|----------|------|----------|
| ID | find_element(By.ID, "login") | 最稳定 |
| NAME | find_element(By.NAME, "q") | 表单字段 |
| CLASS | find_element(By.CLASS_NAME, "title") | 有唯一 class 时 |
| XPATH | find_element(By.XPATH, "//div[@id='main']/p[2]") | 复杂层级 |
| CSS | find_element(By.CSS_SELECTOR, "div.container > p") | 比 XPATH 更简洁 |
| LINK_TEXT | find_element(By.LINK_TEXT, "下一页") | 链接文字 |
4. 等待策略(重要!)
页面加载有快有慢,直接 find_element 可能遇到元素还没出来就查了,导致报错。必须用显式等待:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 等待元素可点击(最多等10秒,每0.5秒查一次)
submit_btn = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "submit"))
)
submit_btn.click()
# 常用等待条件
EC.presence_of_element_located() # 元素出现在 DOM 中
EC.visibility_of_element_located() # 元素可见
EC.element_to_be_clickable() # 元素可点击
EC.text_to_be_present_in_element() # 元素包含指定文字
5. 集成到 pytest
# conftest.py
import pytest
from selenium import webdriver
@pytest.fixture(scope="function")
def browser():
options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
driver = webdriver.Chrome(options=options)
yield driver
driver.quit()
# test_ui.py
def test_homepage_title(browser):
browser.get("https://shaoda.net")
assert "绍大技术网" in browser.title
def test_search_functionality(browser):
browser.get("https://shaoda.net")
browser.find_element(By.NAME, "q").send_keys("Python")
browser.find_element(By.NAME, "q").send_keys(Keys.RETURN)
assert "Python" in browser.page_source
运行:
pytest test_ui.py -v --html=report.html
---
运行效果
$ pytest test_ui.py -v
test_ui.py::test_homepage_title PASSED [ 50%]
test_ui.py::test_search_functionality PASSED [100%]
======================== 2 passed ========================
---
常见问题
Q1: 报 "chromedriver not found"?
用 webdriver_manager 自动管理:from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
Q2: 元素定位找不到?
1. 检查 HTML 是否在 iframe 里(需要switch_to.frame)
2. 检查是否需要滚动到视口(scroll_into_view)
3. 加显式等待,不要用 time.sleep()
Q3: headless 模式有些功能测不了?
文件上传、某些 JS 事件在 headless 下行为不同,建议开发调试时用有界面模式,生产 CI 用 headless。---
延伸阅读
- [[Selenium 滚动与 JavaScript 注入]] — 处理懒加载页面
- [[pytest + Selenium 最佳实践]] — Page Object 模式
- [[Selenium 浏览器指纹反爬]] — 如何绕过检测
---
有问题欢迎在评论区交流!