Playwright Python 浏览器自动化指南:从第一条脚本到 CI 流水线
【免费下载链接】playwright-pythonPython version of the Playwright testing and automation library.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright-python
如果你需要写脚本替人打开网页、填表单、点按钮,甚至把这些步骤搬进 CI 定时跑,可以试试 Playwright Python——一个用 Python 驱动浏览器的自动化库。
它是怎么工作的
Playwright Python 本体是个薄薄的 Python 客户端,脏活累活交给它捆绑的 Node.js 驱动进程干。Python 侧发出 API 调用,驱动通过浏览器引擎的调试协议把指令送进去:Chromium 走 CDP,Firefox 和 WebKit 各走各的通道。浏览器二进制不用你自己折腾,随包配套、版本锁定,playwright install一条命令拉齐。同一套 API 在三个引擎上行为一致,写一次测试,换引擎不用改代码。
还有个容易被低估的设计:每个操作都自带等待。元素没渲染出来、还不可点击,调用会先挂着等条件满足,而不是立刻抛错。很多自动化脚本写得飘,根子就在缺了这层机制。
| Playwright Python | Selenium | |
|---|---|---|
| 浏览器 | 自带二进制,一条命令装好 | 需自行管理各浏览器驱动 |
| 等待 | 操作前自动等待就绪 | 显式/隐式等待要手写 |
| 网络层 | 内置请求拦截与改写 | 依赖第三方扩展 |
核心实现在 playwright/_impl/ 目录,想确认某个行为的细节可以直接翻源码。
安装与第一次运行
环境两条命令就够,第二条会把配套浏览器自动下载到本机:
pip install playwright playwright install第一次安装会下载三个引擎的二进制,体积不小,耐心等它跑完。下面这个最小脚本只做一件事:打开 example.com 并截图,同步 API 适合脚本和测试,高并发场景换 async_api 即可:
from playwright.sync_api import sync_playwright with sync_playwright() as p: # 高并发可换 async_api browser = p.chromium.launch() page = browser.new_page() page.goto('https://example.com') page.screenshot(path='example.png') browser.close()跑通后终端没有多余输出,当前目录会多出一个example.png,打开就是那张 example.com 的截图。仓库里也留了个能直接跑的脚本,scripts/example_sync.py 就是它的完整版。
核心能力拆解
元素定位与交互
写脚本最高频的动作,就是找到元素再对它下手。locator 系列方法把"找"和"做"合成一步,元素还没出现就自动等,省掉大量手写轮询代码。
这段代码演示三种常见写法:按输入框占位符、按按钮角色加名称、按选择器取值:
page.get_by_placeholder('邮箱').fill('you@example.com') page.get_by_role('button', name='登录').click() print(page.locator('h1').inner_text())登录表单、后台列表这类页面,基本就是这套组合拳。
网络请求拦截
不少页面的数据来自接口,直接换掉接口响应,比去戳 DOM 又快又稳。route 把请求拦在发出时,放行、改写、伪造响应都在回调里决定。
这段代码拦截全部请求,只把 /api/data 换成假数据,其余原样放行:
def handle(route): if route.request.url.endswith('/api/data'): route.fulfill(status=200, content_type='application/json', body='{"items": ["mock"]}'). else: route.continue_() page.route('**/*', handle)接口 mock、屏蔽广告请求、模拟弱网失败,都是同一招。
截图与状态捕获
回归测试要留证据,自动化抓取要先确认页面稳定。screenshot 支持整页和单元素两种粒度,配 wait_for_load_state 保证截到的是加载完成的状态。
这段代码等网络空闲后整页截图,再单独截下页头区域:
page.wait_for_load_state('networkidle') page.screenshot(path='full.png', full_page=True) page.get_by_role('banner').screenshot(path='header.png')用例失败时自动附上这两张图,排查就不用凭印象。更多真实用法可以看 tests/async/ 目录里的用例。
从 Demo 到生产
并行执行:用例一多,串行就要等到天黑。pytest 的 worker 分片配上 Playwright 的独立 browser context 就很顺——每个用例拿自己的 context,cookie 和缓存互不串味;浏览器进程按 worker 复用,不必每个用例都冷启动一次。
移动设备模拟:响应式布局"在开发机上看着没问题"不算数。browser.new_context(**p.devices['iPhone 13 Pro'])一行就能套用内置设备描述符,视口、UA、触摸全部就位,tap 事件也直接可测。
CI 接入:本地跑通不等于流水线能跑。CI 镜像里记得用playwright install --with-deps把系统依赖一次补齐,再把截图、HAR 存成构建产物,失败时不用重跑就能复盘。tests/conftest.py 里能看到浏览器参数化与 fixture 的组织方式,搬进自己的项目不费劲。
容易踩的坑
- Executable doesn't exist,找不到浏览器→ 只装了 Python 包,浏览器二进制是另一件事 → 补一句
playwright install再跑。 - strict mode violation,一次命中好几个元素→ 选择器范围太大,页面里有多个同角色节点 → 先用
page.locator('nav')缩小范围再定位,或加.first。 - 本地正常,CI 上页面白屏或崩溃→ 浏览器二进制和驱动版本没对上,或系统库缺失 → 锁定 playwright 版本,CI 里统一用
playwright install --with-deps。 - Jupyter 或 FastAPI 里报 cannot run the nested event loop→ sync API 塞不进已经在运行的 asyncio 循环 → 这类环境统一切到
async_api。
写在最后
回到开头那个场景:替人打开网页、填表单、留证据,然后搬进流水线定时跑。Playwright Python 把环境安装、元素等待、网络控制这些最容易劝退的环节都兜住了,你剩下的精力基本都花在业务断言上。下一步很具体:把两条安装命令和那个最小截图脚本在机器上跑一遍,打开 example.png 确认一切如你所想,再顺着 tests/ 目录看真实用例是怎么写的。
【免费下载链接】playwright-pythonPython version of the Playwright testing and automation library.项目地址: https://gitcode.com/GitHub_Trending/pl/playwright-python
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考