夏日幽灵 サマーゴースト (2021)
Python 自动化浏览器实践 python auto 自动化 Selenium Playwright Python
993 字
5 分钟
Python 自动化浏览器实践
为什么要让浏览器自动跑
日常测试、数据采集、批量操作后台系统时,手点页面既低效又容易出错。Python 生态提供了多种浏览器自动化方案,可以在保留真实渲染环境的情况下完成登录、数据抓取、导出报告等任务。
常用框架对比:
| 工具 | 特点 | 适合场景 |
|---|---|---|
| Selenium | 历史悠久,生态丰富,与各大浏览器兼容 | UI 自动化测试、旧系统兼容 |
| Playwright | 现代、API 简洁,自带浏览器管理 | 多语言支持、高并发采集 |
| Requests + browsercookie | 无头访问,绕过浏览器成本 | 已有 Cookie/Token、接口稳定 |
以下内容以 Selenium 与 Playwright 为主线,补充一些工程化实践。
环境准备
python -m venv .venvsource .venv/bin/activate # Windows 使用 .venv\Scripts\activatepip install --upgrade pippip install selenium~=4.21 webdriver-manager~=4.0 playwright~=1.44playwright install chromiumwebdriver-manager可自动下载匹配版本的浏览器驱动;若内网环境,请预下载并配置PATH。- Playwright 自带浏览器二进制,执行
playwright install即可。 - 建议把这些安装写进
requirements.txt或pyproject.toml,方便 CI/CD 复现。
Selenium 抓取接口 Token
部分前端只在浏览器里发请求,需要我们在网络日志里捕获 Token。下方示例基于 Chrome DevTools Protocol:
import jsonimport timeimport urllib.parse
from selenium import webdriverfrom selenium.webdriver.common.desired_capabilities import DesiredCapabilitiesfrom selenium.webdriver.support.wait import WebDriverWaitfrom selenium.webdriver.support import expected_conditions as ECfrom 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:了解网络日志结构的最佳资料。