Selenium 入门到实战:用 Python 写出稳定的浏览器自动化

Selenium 入门到实战:用 Python 写出稳定的浏览器自动化

浏览器自动化并不只是"让鼠标自己点"。理解 WebDriver、元素定位和等待策略,才能把脚本变成可靠、可维护的测试工具。

https://github.com/lfl171/Selenium.git

目录

  1. [Selenium 是什么](#Selenium 是什么)
  2. 一次自动化如何工作
  3. [准备 Python 环境](#准备 Python 环境)
  4. 第一个完整示例
  5. 元素定位:稳定性从这里开始
  6. 等待动态页面,而不是猜时间
  7. 常见交互与浏览器控制
  8. 让测试更可靠的实践
  9. 从本机走向并行执行
  10. 适用边界与总结

Selenium 是什么

Selenium 是一组浏览器自动化工具与库的集合。对大多数测试和脚本开发者来说,核心入口是 Selenium WebDriver:它通过浏览器原生支持的自动化接口,像用户一样打开页面、查找元素并执行交互。WebDriver 是 W3C 标准,因此同一套测试思路可以应用到 Chrome、Firefox、Edge、Safari 等浏览器。

它常用于端到端(E2E)测试、跨浏览器验证、重复性后台操作,以及需要真实浏览器行为的网页流程。Selenium 不是网页抓取的万能工具,也不会自动判断页面"正确";你仍然需要为关键行为编写清晰的断言。

一次自动化如何工作

text 复制代码
Python 测试脚本 → Selenium WebDriver → 浏览器驱动 / Selenium Manager → 浏览器

脚本通过 Selenium 的语言绑定发出命令,浏览器驱动负责把命令交给具体浏览器并返回结果。较新的 Selenium 绑定会通过 Selenium Manager 协助管理驱动程序;它减少了手动下载和匹配驱动的工作,但运行环境仍需具备受支持的浏览器,并允许相应的驱动管理流程完成。

Selenium 项目还包含 Selenium IDE(录制与回放)和 Selenium Grid(远程及并行浏览器执行)等工具。不要把它们和 WebDriver 的职责混为一谈:写代码控制浏览器的核心仍是 WebDriver。

准备 Python 环境

建议在项目虚拟环境中安装 Selenium:

bash 复制代码
python -m venv .venv
# macOS / Linux
source .venv/bin/activate
# Windows PowerShell 可使用:.venv\Scripts\Activate.ps1
python -m pip install selenium

确认本机安装了计划测试的浏览器。对于较新的 Selenium,通常可以先尝试直接启动浏览器;如果网络策略、浏览器版本或企业环境限制导致自动管理失败,再根据官方文档配置对应驱动。

第一个完整示例

下面的脚本访问 Selenium 官方演示页,输入搜索词并验证页面标题。它展示了测试中最重要的几个动作:建立会话、定位元素、等待页面状态、执行操作、断言结果,并在结束时关闭浏览器。

python 复制代码
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)

try:
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")

    text_box = wait.until(
        EC.visibility_of_element_located((By.NAME, "my-text"))
    )
    text_box.send_keys("Selenium WebDriver")
    driver.find_element(By.CSS_SELECTOR, "button").click()

    message = wait.until(
        EC.visibility_of_element_located((By.ID, "message"))
    )
    assert message.text == "Received!"
    print("表单提交成功:", message.text)
finally:
    driver.quit()

try/finally 可以确保即便断言失败也会退出浏览器会话。真实项目中,常把创建和清理逻辑放进 pytest fixture,让每个测试都能获得独立、可预期的浏览器状态。

元素定位:稳定性从这里开始

Selenium 提供 ID、名称、CSS 选择器、XPath、链接文字等定位方式。优先选择唯一、语义清晰且不容易随布局变化 的属性。若你能影响应用代码,为关键控件添加稳定的 data-testid 往往很有帮助。

python 复制代码
from selenium.webdriver.common.by import By

submit = driver.find_element(By.ID, "submit")
email = driver.find_element(By.NAME, "email")
save = driver.find_element(By.CSS_SELECTOR, "button[data-testid='save']")

可以把定位器集中定义,让页面结构变化时更容易维护:

python 复制代码
class LoginPage:
    EMAIL = (By.NAME, "email")
    PASSWORD = (By.NAME, "password")
    SUBMIT = (By.CSS_SELECTOR, "button[data-testid='login']")

XPath 适合 CSS 难以表达的关系或文本场景,但复杂、依赖页面层级的 XPath 往往很脆弱。避免使用诸如"页面第 3 个 div 下面的第 2 个按钮"这类只描述当前布局的定位器。

等待动态页面,而不是猜时间

现代网页经常在首屏加载后继续通过 JavaScript 更新内容。driver.get() 返回并不代表目标控件已经可交互。固定的 time.sleep(5) 每次都浪费时间,而且网络或机器变慢时仍可能失败。

更好的做法是等待具体条件:

python 复制代码
wait = WebDriverWait(driver, 10)
button = wait.until(
    EC.element_to_be_clickable((By.ID, "continue"))
)
button.click()

常用条件包括元素可见、元素可点击、元素存在、文字出现以及页面标题匹配。隐式等待是针对元素查找的全局设置;显式等待则能准确描述当前步骤所需要的状态。不要混用隐式等待和显式等待,否则实际等待时间可能难以预测。

常见交互与浏览器控制

python 复制代码
# 文本框
search = driver.find_element(By.NAME, "q")
search.clear()
search.send_keys("browser automation")

# 下拉框(原生 select)
from selenium.webdriver.support.ui import Select
Select(driver.find_element(By.ID, "country")).select_by_value("cn")

# 截图与窗口
driver.save_screenshot("failure.png")
driver.maximize_window()

复选框、单选框和按钮通常可以用 click() 操作;文件上传则通常通过向 <input type="file"> 发送文件路径完成。对于新窗口、iframe、悬停和键盘组合等场景,应先显式切换到正确的窗口或 frame,再执行定位和交互。操作之后最好等待可观察的页面变化,而不是假设点击必然成功。

让测试更可靠的实践

  • 断言用户可见的结果。 点击成功不等于业务操作成功;检查确认信息、状态变化或导航结果。
  • 每个测试独立准备状态。 避免测试间依赖执行顺序或共享浏览器残留数据。
  • 采用 Page Object 管理复杂页面。 把定位器和页面操作封装起来,让测试用业务语言表达意图。
  • 保留失败证据。 失败时收集截图、当前 URL、控制台日志和必要的页面信息,缩短排查时间。
  • 优先修复不稳定根因。 如果测试偶发失败,检查等待条件、定位器稳定性、测试数据和环境差异,不要只增加超时时间。
  • 把浏览器和测试环境版本纳入 CI。 本地通过、流水线失败常常来自浏览器版本、网络、并发或数据隔离差异。

一个好的测试读起来像一段可验证的用户旅程:准备 → 操作 → 等待 → 断言 → 清理。

从本机走向并行执行

当测试需要覆盖多种浏览器,或希望在 CI 中并行运行时,可以考虑 Selenium Grid。Grid 让测试代码连接远端执行环境,由其分配浏览器会话。扩展之前,先保证单个测试可重复、数据互不干扰,并设置合理的超时和失败诊断;并行会放大测试本身的竞态问题。

Selenium 也在推进 WebDriver BiDi,用于双向、事件驱动的浏览器通信,例如订阅网络或控制台事件。具体能力会随浏览器和 Selenium 版本而异,使用前请查看官方文档的支持情况。

适用边界与总结

如果目标是验证真实浏览器中的用户流程,Selenium 是成熟且跨浏览器的选择。如果只需快速请求静态页面,直接使用 HTTP 客户端通常更简单;若测试侧重组件内部逻辑,则单元测试往往更快、更聚焦。合理的测试组合会让端到端测试覆盖关键路径,而不是承担所有验证工作。

记住三件事:用稳定定位器找到元素,用显式等待描述页面状态,用断言验证用户结果。 做到这三点,你的 Selenium 脚本就会从"能跑一次"逐渐变成团队可以长期维护的测试资产。

延伸阅读

相关推荐
汤米粥1 小时前
后端开发主流技术方案
java·python·golang·php·nodejs·后端开发
我的xiaodoujiao1 小时前
Django 基础知识详细图文教程 13-Django 模型定义与使用 3
数据库·后端·python·测试工具·oracle·django
小静AI工程实验室1 小时前
robots.txt 不是门禁:RFC 9309 规则、缓存与 Python 爬虫的 10 个边界
爬虫·python·缓存
沉下心来学鲁班1 小时前
DeepAgents 记忆机制:让 AI Agent 拥有“跨对话“的记忆
服务器·人工智能·python
Helix2501 小时前
Python与其他编程语言优劣势对比:2026初学者选型指南
java·python·教程·编程语言·入门·初学者编程选型
零基础1232 小时前
深度强化学习驱动的 Agent 后训练:原理、实践与前沿路线
人工智能·python·机器学习
I Am a robert girl2 小时前
PhysStream 源码级拆解:流式视频生成如何做到“边生成边控制“
python·音视频·源码解析·视频生成·可控生成·流式生成·物理控制
Hello_Pyhx2 小时前
MAA 首次连接模拟器:从 ADB 配置到单项任务验证
自动化·脚本·明日方舟