应使用page.on("response")事件监听响应并读取response.status(),因其触发时响应已就绪;page.route适用于需修改请求或mock响应的场景,仅监控状态码时response事件更轻量稳定。

用 page.route 拦截请求并读取响应状态码
Playwright 默认不暴露响应状态码,必须主动拦截请求并等待响应完成。关键不是监听请求发起,而是等它真正返回后抓取 response.status()。
常见错误是只用 page.on("request") —— 这时响应还没回来,request.response() 为 None,直接调用会报 AttributeError。
- 必须用
page.route或page.on("response"),后者更轻量且足够用 -
page.on("response")触发时,响应已就绪,可安全调用response.status() - 如果需修改请求(如 mock),才用
page.route;仅监控状态码,response事件更稳
page.on("response", lambda response: print(f"{response.url} -> {response.status()}"))
如何过滤特定 URL 或状态码范围?
全量打印会淹没关键信息,实际监控通常关注 4xx/5xx 或某类接口(如 /api/)。别在回调里写复杂判断,先提取 URL 和状态再分支处理。
- 用
response.url做字符串匹配或urllib.parse.urlparse解析路径 - 状态码判断放回调内部,避免额外事件注册开销
- 注意重定向:301/302 也会触发
response事件,若只关心最终结果,要结合response.request().redirectedFrom()判断是否为重定向链中间节点
page.on("response", lambda r: print(r.url, r.status()) if r.status() >= 400 else None)
为什么 page.wait_for_response 不适合实时监控?
page.wait_for_response 是同步等待单次响应,适用于断言某个请求是否返回指定状态码(比如测试场景),但无法持续捕获所有网络请求的状态变化。
立即学习“Python免费学习笔记(深入)”;
- 它会阻塞执行,直到匹配到一个响应或超时,不能作为长期监听机制
- 无法区分并发请求,多次调用容易漏掉中间响应
- 若配合
page.goto使用,只能捕获页面加载过程中的部分请求,AJAX 后续调用可能错过
实时监控必须依赖事件监听,而非一次性等待。
注意异步上下文和作用域泄漏
在 async 函数中注册 page.on("response") 时,回调函数本身默认是同步的。如果在里面做 await 操作(比如写日志到文件、发告警),必须显式声明为 async 并用 page.on("response", async_callback),否则会报 RuntimeWarning: coroutine was never awaited。
- Playwright 的事件系统不自动支持 async 回调,需手动包装
- 避免在回调里直接调用
await page.screenshot()等耗时操作,会拖慢整个页面网络栈 - 若需异步处理,建议把数据推入队列,由单独任务消费,保持事件回调轻量
状态码本身只是整数,但背后涉及请求生命周期、重定向链、跨域限制和资源类型(比如 fetch vs iframe 加载),这些细节不显式处理时,很容易误判失败原因。


















