建立自己的網(wǎng)站平臺(tái)需多少錢優(yōu)化系統(tǒng)軟件
介紹
Playwright 提供 API 來監(jiān)控和修改瀏覽器網(wǎng)絡(luò)流量,包括 HTTP 和 HTTPS。頁(yè)面執(zhí)行的任何請(qǐng)求,包括?XHR?和獲取請(qǐng)求,都可以被跟蹤、修改和處理。
模擬接口
查看我們的?API 模擬指南,了解有關(guān)如何
- 模擬 API 請(qǐng)求,從不命中 API
- 執(zhí)行 API 請(qǐng)求并修改響應(yīng)
- 使用 HAR 文件模擬網(wǎng)絡(luò)請(qǐng)求。
HTTP身份驗(yàn)證
執(zhí)行 HTTP 身份驗(yàn)證。
- 同步
context = browser.new_context(http_credentials={"username": "bill", "password": "pa55w0rd"}
)
page = context.new_page()
page.goto("https://example.com")
HTTP 代理
您可以將頁(yè)面配置為通過 HTTP(S) 代理或 SOCKSv5 加載??梢詾檎麄€(gè)瀏覽器全局設(shè)置代理,也可以為每個(gè)瀏覽器上下文單獨(dú)設(shè)置代理。
您可以選擇為 HTTP(S) 代理指定用戶名和密碼,也可以指定要繞過代理的主機(jī)。
下面是全局代理的示例:
- 同步
browser = chromium.launch(proxy={"server": "http://myproxy.com:3128","username": "usr","password": "pwd"
})
當(dāng)為每個(gè)上下文單獨(dú)指定代理時(shí),Windows 上的 Chromium?需要一個(gè)提示,指示將設(shè)置代理。這是通過將非空代理服務(wù)器傳遞給瀏覽器本身來完成的。下面是特定于上下文的代理的示例:
- 同步
# 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"})
網(wǎng)絡(luò)事件
您可以監(jiān)視所有請(qǐng)求和響應(yīng):
- 同步
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()的網(wǎng)絡(luò)響應(yīng):
# 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
處理請(qǐng)求
page.route("**/api/fetch_data",lambda route: route.fulfill(status=200, body=test_data))
page.goto("https://example.com")
修改請(qǐng)求
# 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"))
您可以通過修改繼續(xù)請(qǐng)求。上面的示例從傳出請(qǐng)求中刪除 HTTP 標(biāo)頭。
終止請(qǐng)求?
您可以使用?page.route() 和?route.abort()?中止請(qǐng)求。
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_())
修改響應(yīng)
要修改響應(yīng),請(qǐng)使用?APIRequestContext?獲取原始響應(yīng),然后將響應(yīng)傳遞給?route.fulfill()。您可以通過以下選項(xiàng)覆蓋響應(yīng)上的各個(gè)字段:
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)
網(wǎng)絡(luò)套接字
Playwright支持開箱即用的WebSockets檢查。每次創(chuàng)建 WebSocket 時(shí),都會(huì)觸發(fā)?page.on(“websocket”)?事件。此事件包含用于進(jìn)一步檢查 Web 套接字幀的?WebSocket?實(shí)例:
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框架來監(jiān)聽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')# 執(zhí)行其他操作...browser.close()
```
在上述示例中:
?創(chuàng)建一個(gè)新的頁(yè)面,并使用`page.route`方法來監(jiān)聽符合指定URL規(guī)則的WebSocket事件。在這個(gè)例子中,我們?cè)O(shè)置URL規(guī)則為`**/websocket_endpoint`,您需要根據(jù)實(shí)際情況替換為您要監(jiān)聽的WebSocket端點(diǎn)。
缺少網(wǎng)絡(luò)事件和服務(wù)工作線程
Playwright的內(nèi)置browser_context.route()和page.route()允許你的測(cè)試在本地路由請(qǐng)求并執(zhí)行模擬和攔截。
- 如果您使用的是 Playwright 的本機(jī) browser_context.route() 和 page.route(),并且似乎缺少網(wǎng)絡(luò)事件,請(qǐng)通過將 設(shè)置為 來禁用 Service Worker 。
browser.new_context.service_workers
'block'
- 可能是您正在使用模擬工具,例如模擬服務(wù)輔助角色 (MSW)。雖然此工具開箱即用地用于模擬響應(yīng),但它添加了自己的 Service Worker 來接管網(wǎng)絡(luò)請(qǐng)求,從而使它們對(duì)?browser_context.route() 和 page.route()?不可見。如果您對(duì)網(wǎng)絡(luò)測(cè)試和模擬都感興趣,請(qǐng)考慮使用內(nèi)置的?browser_context.route() 和?page.route()?進(jìn)行響應(yīng)模擬。
- 如果您不僅對(duì)使用 Service Worker 進(jìn)行測(cè)試和網(wǎng)絡(luò)模擬感興趣,還對(duì)路由和偵聽 Service Worker 自己發(fā)出的請(qǐng)求感興趣,請(qǐng)參閱此實(shí)驗(yàn)性功能。