当目标页面依赖 JavaScript 渲染、传统 HTTP 抓取拿到的只是一具空壳 HTML 时,你需要的是真正能驱动浏览器的工具。Playwright 是微软开源的 Web 自动化与测试框架,统一 API 驱动 Chromium、Firefox 与 WebKit 三大内核,GitHub 上约 75k Star,Apache-2.0 协议。本文依次介绍它的能力全景、Python 环境的安装上手、采集与测试中的核心 API,最后给出与 Selenium 的对比和实战注意事项。
1、项目概述
Playwright 的官方定位是"web automation and testing framework"——一套 API 同时覆盖自动化测试、浏览器脚本和数据采集三类场景。它最吸引人的一点是浏览器覆盖度:同一份代码可以跑在 Chromium、Firefox 和 WebKit 上,且官方维护各内核的预编译版本,Linux、macOS、Windows 全平台支持。
除了多浏览器,几个工程级特性让它区别于老一代工具。
- 自动等待:操作前自动等元素可交互,断言自动重试
- 上下文隔离:每个测试用独立的浏览器上下文,互不污染
- 失败诊断:失败时自动留存 trace、截图与视频
- 默认并行执行,多语言绑定:Python、.NET、Java
近期版本还加入了 MCP 服务器与面向编程代理的 CLI,让 AI 代理通过无障碍树直接操作页面,这条路线值得持续关注。
2、安装与快速上手
以 Python 为例,安装分两步:装库、装浏览器二进制。第二步是新手最常漏掉的。
pip install playwright
playwright install
playwright install 会下载 Chromium、Firefox、WebKit 的官方构建,国内网络环境下建议先设置镜像代理。装好后用官方首页截图脚本验证环境是否就绪。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://playwright.dev/")
page.screenshot(path="screenshot.png")
browser.close()
这段代码是 Playwright 的最小闭环:launch 起浏览器、new_page 开页面、goto 导航、screenshot 截图。跑通后你手上的就是一个可编程的完整浏览器。Node.js 侧则是 npm init playwright@latest 一条命令完成脚手架。
3、页面采集核心 API
采集场景下最高频的是三件事:等待渲染、提取内容、拦截网络。Playwright 对应的能力分别是 wait_for 系列、定位器(locator)与 page.route()。
等待渲染建议用 page.wait_for_selector() 或 page.wait_for_load_state("networkidle"),后者适合异步加载繁重的单页应用。提取内容用定位器链,语义化且自动等待,例如 page.get_by_role("heading").all_text_contents() 一行拉取全部标题。
网络拦截的典型用法是屏蔽图片、只留数据请求,能显著提速并降低被识别概率。README 中的示例一行完成图片拦截。
page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())
route 的回调里也可以 route.fetch() 拿到响应体再 route.fulfill() 回填,等于在浏览器层做了一层可编程代理。配合 page.on("response") 监听接口返回,很多站点不需要解析 DOM,直接截获 JSON 接口即可完成采集。
4、测试场景与反检测
做端到端测试时,Playwright 提供了独立的 @playwright/test 包(Python 侧为 pytest-playwright 插件),自带 expect 断言与并行执行器。README 中的测试示例长这样。
test("has title", lambda page: (
page.goto("https://playwright.dev/"),
expect(page).to_have_title(re.compile("Playwright")),
))
Python 生态里更常见的写法是配合 pytest fixture,浏览器与上下文的生命周期由插件管理,登录态可通过 storage_state() 导出复用,省去每个用例重复登录。
采集侧的反检测要点:优先用 browser.new_context() 时设定真实的 user_agent 与 locale;需要移动端环境时,官方设备描述符一行模拟整机。README 中的示例是模拟 iPhone 15。
context = browser.new_context(devices["iPhone 15"])
注意 Playwright 驱动的是真实内核,指纹特征与无头检测仍是攻防重点,重度反爬场景可考虑 playwright-stealth 之类的补丁。
5、与 Selenium 对比选型
| 维度 | Playwright | Selenium |
|---|---|---|
| 浏览器支持 | 三内核官方构建 | 依赖各浏览器驱动 |
| 等待机制 | 自动等待 | 手写显式等待 |
| 并行能力 | 内置 | 需自建网格 |
| 生态历史 | 较新 | 极其成熟 |
结论比较明确:新项目选 Playwright,自动等待与失败 trace 能省下大量调试时间;Selenium 的优势在存量系统、IE 兼容与超成熟的社区资料。与 HTTP 层框架的分工也简单——渲染重的站用 Playwright,接口清晰的站用 httpx,两者混用时让 Playwright 专职渲染、HTTP 层交给采集管线。
6、总结
Playwright 把跨浏览器、自动等待、上下文隔离、失败录制这几件自动化里最费人力的部分做成了默认行为,无论写测试还是做采集,代码量都比上一代工具低一个量级。对于测试工程师,建议直接用 pytest-playwright 起步并把 trace viewer 纳入日常排障流程;对于采集工程师,建议先用 page.route 与接口监听判断能否绕过 DOM 解析,再考虑整页渲染。项目地址:microsoft/playwright,文档见 playwright.dev。


