夏日幽灵 サマーゴースト (2021)
993 字
5 分钟
Python 自动化浏览器实践
为什么要让浏览器自动跑
日常测试、数据采集、批量操作后台系统时,手点页面既低效又容易出错。Python 生态提供了多种浏览器自动化方案,可以在保留真实渲染环境的情况下完成登录、数据抓取、导出报告等任务。
常用框架对比:
| 工具 | 特点 | 适合场景 |
|---|---|---|
| Selenium | 历史悠久,生态丰富,与各大浏览器兼容 | UI 自动化测试、旧系统兼容 |
| Playwright | 现代、API 简洁,自带浏览器管理 | 多语言支持、高并发采集 |
| Requests + browsercookie | 无头访问,绕过浏览器成本 | 已有 Cookie/Token、接口稳定 |
以下内容以 Selenium 与 Playwright 为主线,补充一些工程化实践。
环境准备
python -m venv .venv
source .venv/bin/activate # Windows 使用 .venv\Scripts\activate
pip install --upgrade pip
pip install selenium~=4.21 webdriver-manager~=4.0 playwright~=1.44
playwright install chromium
webdriver-manager可自动下载匹配版本的浏览器驱动;若内网环境,请预下载并配置PATH。- Playwright 自带浏览器二进制,执行
playwright install即可。 - 建议把这些安装写进
requirements.txt或pyproject.toml,方便 CI/CD 复现。
Selenium 抓取接口 Token
部分前端只在浏览器里发请求,需要我们在网络日志里捕获 Token。下方示例基于 Chrome DevTools Protocol:
import json
import time
import urllib.parse
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
def get_token(timeout: int = 15) -> str | None:
caps = DesiredCapabilities.CHROME
caps["goog:loggingPrefs"] = {"performance": "ALL"}
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--disable-gpu")
options.add_argument("--window-size=1280,720")
driver = webdriver.Chrome(options=options, desired_capabilities=caps)
target_url = "https://vp.fact.qq.com/home"
api_pattern = "/api/config/initial"
try:
driver.get(target_url)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.CSS_SELECTOR, "[data-page-ready]"))
)
start_time = time.time()
token = None
while time.time() - start_time < timeout and not token:
for log_item in driver.get_log("performance"):
message = json.loads(log_item["message"])["message"]
if message.get("method") != "Network.requestWillBeSent":
continue
request = message["params"]["request"]
url = request.get("url", "")
if api_pattern in url:
parsed = urllib.parse.urlparse(url)
qs = urllib.parse.parse_qs(parsed.query)
token = qs.get("token", [None])[0]
break
if token:
print("捕获 Token:", token)
else:
print("未在超时时间内发现 Token")
return token
finally:
driver.quit()
要点归纳:
- 新版 Chrome 建议启用
--headless=new,兼容性更好。 - 加
WebDriverWait确保页面加载完再监听日志。 - 尝试控制循环超时时间,避免长时间阻塞或 CPU 飙升。
Playwright 的替代写法
Playwright 同样能抓取网络请求,并且 API 更直接:
from playwright.sync_api import sync_playwright
def fetch_token(target: str) -> str | None:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
token_holder = {"value": None}
def handle_request(route):
url = route.request.url
if "/api/config/initial" in url:
token_holder["value"] = route.request.url.split("token=")[-1]
route.continue_()
page.route("**/api/config/initial*", handle_request)
page.goto(target, wait_until="networkidle")
browser.close()
return token_holder["value"]
- Playwright 能直接对特定请求做
route拦截,减少日志解析。 wait_until="networkidle"避免页面仍在加载时就关闭浏览器。
自动化常见任务清单
- UI 回归测试:搭配
pytest,为关键流程编写断言,用pytest-xdist并发执行。 - 数据采集:与
pandas、openpyxl结合,把页面数据写出 Excel。 - 批量操作:后台管理系统重复操作(如批量审批、导入),可以沿用录制脚本。
- 截图/录屏:Selenium 可通过
driver.save_screenshot捕获截图;Playwright 原生支持录像page.video. - 下载管理:Playwright 提供
page.expect_download();Selenium 需通过 Chrome 配置download.default_directory。
工程化细节
- 结构化项目:把页面元素封装为 Page Object,可读性和复用度更高。
- 依赖管理:CI 中将浏览器二进制缓存到镜像或制品仓库,缩短冷启动时间。
- 日志与报告:结合
pytest-html或allure生成测试报告,失败时附带截图。 - 定时调度:在 Airflow/Prefect 下运行脚本,统一重试策略与告警。
- Docker 化:使用
selenium/standalone-chrome、mcr.microsoft.com/playwright/python等镜像可避免宿主机缺依赖。
合规与反爬注意事项
- 确认你有权访问目标数据,遵守网站 Robots 协议与法律法规。
- 控制请求频率,通过
time.sleep或队列限流,避免触发风控。 - 对于登录态相关脚本,及时处理 Cookie 过期和验证码;可结合第三方识别服务,但需评估安全风险。
- 生产环境保管好账号、Token 等敏感信息,建议接入 Vault、Secrets Manager。
进一步阅读
- Selenium Docs:官方 WebDriver API 文档。
- Playwright Documentation:详尽示例和调试技巧。
- Chrome DevTools Protocol:了解网络日志结构的最佳资料。


