Selenium + Python:浏览器自动化测试从入门到实战

小飞兽 Python 5 次阅读 2026-07-24

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 浏览器指纹反爬]] — 如何绕过检测

---
有问题欢迎在评论区交流!