介绍
Playwright 提供 API 来监控和修改浏览器网络流量,包括 HTTP 和 HTTPS。页面执行的任何请求,包括 XHR 和获取请求,都可以被跟踪、修改和处理。
模拟接口
查看我们的 API 模拟指南,了解有关如何
- 模拟 API 请求,从不命中 API
- 执行 API 请求并修改响应
- 使用 HAR 文件模拟网络请求。
HTTP身份验证
执行 HTTP 身份验证。
- 同步
context = browser.new_context(http_credentials={"username": "bill", "password": "pa55w0rd"}
)
page = context.new_page()
page.goto("https://example.com")
HTTP 代理
您可以将页面配置为通过 HTTP(S) 代理或 SOCKSv5 加载。可以为整个浏览器全局设置代理,也可以为每个浏览器上下文单独设置代理。
您可以选择为 HTTP(S) 代理指定用户名和密码,也可以指定要绕过代理的主机。
下面是全局代理的示例:
- 同步
browser = chromium.launch(proxy={"server": "http://myproxy.com:3128","username": "usr","password": "pwd"
})
当为每个上下文单独指定代理时,Windows 上的 Chromium 需要一个提示,指示将设置代理。这是通过将非空代理服务器传递给浏览器本身来完成的。下面是特定于上下文的代理的示例:
- 同步
# Browser proxy option is required for Chromium on Windows.
browser = chromium.launch(proxy={"server": "per-context"})
context = browser.new_context(proxy={"server": "http://myproxy.com:3128"})
网络事件
您可以监视所有请求和响应:
- 同步
from playwright.sync_api import sync_playwrightdef run(playwright):chromium = playwright.chromiumbrowser = chromium.launch()page = browser.new_page()# Subscribe to "request" and "response" events.page.on("request", lambda request: print(">>", request.method, request.url))page.on("response", lambda response: print("<<", response.status, response.url))page.goto("https://example.com")browser.close()with sync_playwright() as playwright:run(playwright)
或者等待按钮单击后page.expect_response()的网络响应:
# Use a glob url pattern
with page.expect_response("**/api/fetch_data") as response_info:page.get_by_text("Update").click()
response = response_info.value
# Use a regular expression
with page.expect_response(re.compile(r"\.jpeg$")) as response_info:page.get_by_text("Update").click()
response = response_info.value# Use a predicate taking a response object
with page.expect_response(lambda response: token in response.url) as response_info:page.get_by_text("Update").click()
response = response_info.value
处理请求
page.route("**/api/fetch_data",lambda route: route.fulfill(status=200, body=test_data))
page.goto("https://example.com")
修改请求
# Delete header
def handle_route(route):headers = route.request.headersdel headers["x-secret"]route.continue_(headers=headers)
page.route("**/*", handle_route)# Continue requests as POST.
page.route("**/*", lambda route: route.continue_(method="POST"))
您可以通过修改继续请求。上面的示例从传出请求中删除 HTTP 标头。
终止请求
您可以使用 page.route() 和 route.abort() 中止请求。
page.route("**/*.{png,jpg,jpeg}", lambda route: route.abort())# Abort based on the request type
page.route("**/*", lambda route: route.abort() if route.request.resource_type == "image" else route.continue_())
修改响应
要修改响应,请使用 APIRequestContext 获取原始响应,然后将响应传递给 route.fulfill()。您可以通过以下选项覆盖响应上的各个字段:
def handle_route(route: Route) -> None:# Fetch original response.response = route.fetch()# Add a prefix to the title.body = response.text()body = body.replace("<title>", "<title>My prefix:")route.fulfill(# Pass all fields from the response.response=response,# Override response body.body=body,# Force content type to be html.headers={**response.headers, "content-type": "text/html"},)page.route("**/title.html", handle_route)
网络套接字
Playwright支持开箱即用的WebSockets检查。每次创建 WebSocket 时,都会触发 page.on(“websocket”) 事件。此事件包含用于进一步检查 Web 套接字帧的 WebSocket 实例:
def on_web_socket(ws):print(f"WebSocket opened: {ws.url}")ws.on("framesent", lambda payload: print(payload))ws.on("framereceived", lambda payload: print(payload))ws.on("close", lambda payload: print("WebSocket closed"))page.on("websocket", on_web_socket)
使用Playwright框架来监听WebSocket事件的Python代码示例如下:
from playwright.sync_api import sync_playwrightdef on_websocket(event, websocket):websocket.on('socket', print)websocket.on('close', print)with sync_playwright() as p:browser_type = p.chromiumbrowser = browser_type.launch()context = browser.new_context()page = context.new_page()page.route("**/websocket_endpoint", on_websocket)page.goto('https://example.com')# 执行其他操作...browser.close()
```
在上述示例中:
创建一个新的页面,并使用`page.route`方法来监听符合指定URL规则的WebSocket事件。在这个例子中,我们设置URL规则为`**/websocket_endpoint`,您需要根据实际情况替换为您要监听的WebSocket端点。
缺少网络事件和服务工作线程
Playwright的内置browser_context.route()和page.route()允许你的测试在本地路由请求并执行模拟和拦截。
- 如果您使用的是 Playwright 的本机 browser_context.route() 和 page.route(),并且似乎缺少网络事件,请通过将 设置为 来禁用 Service Worker 。
browser.new_context.service_workers
'block'
- 可能是您正在使用模拟工具,例如模拟服务辅助角色 (MSW)。虽然此工具开箱即用地用于模拟响应,但它添加了自己的 Service Worker 来接管网络请求,从而使它们对 browser_context.route() 和 page.route() 不可见。如果您对网络测试和模拟都感兴趣,请考虑使用内置的 browser_context.route() 和 page.route() 进行响应模拟。
- 如果您不仅对使用 Service Worker 进行测试和网络模拟感兴趣,还对路由和侦听 Service Worker 自己发出的请求感兴趣,请参阅此实验性功能。