Playwright實(shí)現(xiàn)網(wǎng)絡(luò)流量監(jiān)控與修改指南
Playwright 提供了強(qiáng)大的網(wǎng)絡(luò)流量控制能力,可以攔截、修改和分析所有 HTTP/HTTPS 請求。下面我將詳細(xì)介紹各種使用方法和底層原理。
一、基本網(wǎng)絡(luò)監(jiān)控
1. 記錄所有請求
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
# 監(jiān)聽請求和響應(yīng)事件
def print_request(request):
print(f">> Request: {request.method} {request.url}")
def print_response(response):
print(f"<< Response: {response.status} {response.url}")
page.on("request", print_request)
page.on("response", print_response)
page.goto("https://example.com")
browser.close()
2. 獲取請求詳細(xì)信息
def log_request(request):
print(f"""
Request: {request.method} {request.url}
Headers: {request.headers}
Post Data: {request.post_data}
Resource Type: {request.resource_type}
Navigation: {request.is_navigation_request()}
""")
page.on("request", log_request)
二、網(wǎng)絡(luò)請求修改
1. 修改請求頭
async def modify_headers(route):
headers = route.request.headers.copy()
headers["x-custom-header"] = "my-value"
await route.continue_(headers=headers)
await page.route("**/*", modify_headers)
2. 修改請求體
async def modify_post_data(route):
if route.request.method == "POST":
post_data = route.request.post_data
modified_data = post_data.replace("old", "new")
await route.continue_(post_data=modified_data)
else:
await route.continue_()
await page.route("**/api/**", modify_post_data)
3. 攔截并返回模擬響應(yīng)
async def mock_response(route):
await route.fulfill(
status=200,
content_type="application/json",
body=json.dumps({"data": "mocked"})
)
await page.route("**/api/data", mock_response)
三、高級網(wǎng)絡(luò)控制
1. 延遲響應(yīng)
async def delay_response(route):
await asyncio.sleep(2) # 延遲2秒
await route.continue_()
await page.route("**/*.css", delay_response)
2. 阻止特定請求
async def block_analytics(route):
if "google-analytics" in route.request.url:
await route.abort()
else:
await route.continue_()
await page.route("**/*", block_analytics)
3. 修改響應(yīng)
async def modify_response(route):
response = await route.fetch()
body = await response.text()
modified_body = body.replace("Original", "Modified")
await route.fulfill(
response=response,
body=modified_body
)
await page.route("**/api/content", modify_response)
四、底層運(yùn)行原理
1. 整體架構(gòu)
+-------------------+ +-------------------+ +-------------------+
| Playwright | | Browser | | Remote Server |
| Python Client |<--->| (Chromium/etc) |<--->| (example.com) |
+-------------------+ +-------------------+ +-------------------+
| ^ ^
| CDP (Chrome DevTools) | |
| WebSocket Connection | | Actual Network Traffic
v | |
+-------------------+ | |
| Network Proxy |-----------+ |
| Layer |----------------+
+-------------------+
2. 請求生命周期
1.初始化階段:
- 當(dāng)調(diào)用
page.route()時,Playwright 會在瀏覽器中設(shè)置請求攔截器 - 通過 CDP 的
Fetch域啟用請求攔截
2.請求攔截流程:
sequenceDiagram
participant Page
participant Playwright
participant Browser
Page->>Browser: 發(fā)起請求
Browser->>Playwright: 觸發(fā)請求攔截 (Fetch.requestPaused)
Playwright->>Python: 調(diào)用注冊的路由處理器
alt 繼續(xù)請求
Python->>Playwright: route.continue_()
Playwright->>Browser: 繼續(xù)請求到服務(wù)器
else 模擬響應(yīng)
Python->>Playwright: route.fulfill()
Playwright->>Browser: 返回模擬響應(yīng)
else 中止請求
Python->>Playwright: route.abort()
Playwright->>Browser: 中止請求
end
3.修改請求流程:
Playwright 使用中間人技術(shù)攔截請求
可以修改的部分包括:
- URL
- 方法 (GET/POST等)
- 請求頭
- 請求體
- 重定向行為
4.響應(yīng)處理流程:
對于 route.fetch() 操作:
- Playwright 會實(shí)際發(fā)送請求到服務(wù)器
- 獲取響應(yīng)后允許修改再返回給頁面
對于 route.fulfill() 操作:
- 直接構(gòu)造響應(yīng)返回給瀏覽器
- 不接觸真實(shí)服務(wù)器
3. 關(guān)鍵技術(shù)點(diǎn)
1.請求匹配系統(tǒng):
- 使用 glob 模式或正則表達(dá)式匹配 URL
- 可以按資源類型 (XHR, stylesheet, image等) 過濾
2.內(nèi)存管理:
- 每個路由處理器都保持引用直到手動取消
- 需要調(diào)用
page.unroute()避免內(nèi)存泄漏
3.安全機(jī)制:
- HTTPS 攔截需要 Playwright 安裝自己的 CA 證書
- 修改后的請求仍保持安全特性
- 遵循同源策略和 CORS 規(guī)則
4.性能優(yōu)化:
- 攔截器運(yùn)行在瀏覽器進(jìn)程中
- 最小化 Python 和瀏覽器之間的通信
- 批量處理多個請求
五、實(shí)際應(yīng)用示例
1. API 測試模擬
async def test_api(page):
async def handle_api(route):
if route.request.method == "POST":
await route.fulfill(
status=201,
json={"id": 123, "status": "created"}
)
else:
await route.continue_()
await page.route("**/api/users*", handle_api)
# 測試代碼
await page.goto("https://app.example.com")
await page.click("#create-user")
assert await page.text_content(".status") == "User 123 created"
2. 性能分析
async def analyze_performance(page):
requests = []
def log_request(request):
requests.append({
"url": request.url,
"start": time.time(),
"type": request.resource_type
})
def log_response(response):
for req in requests:
if req["url"] == response.url:
req["duration"] = time.time() - req["start"]
req["status"] = response.status
page.on("request", log_request)
page.on("response", log_response)
await page.goto("https://example.com")
# 輸出性能報告
slow_requests = [r for r in requests if r.get("duration", 0) > 1]
print(f"Slow requests: {len(slow_requests)}/{len(requests)}")
3. 認(rèn)證處理
async def handle_auth(page):
await page.route("**/api/**", lambda route: route.continue_(
headers={**route.request.headers, "Authorization": "Bearer xyz"}
))
await page.goto("https://app.example.com")
# 所有API請求會自動帶上認(rèn)證頭
六、最佳實(shí)踐
1.精確路由匹配:
- 避免使用太寬泛的
**/*模式 - 結(jié)合 URL 和資源類型進(jìn)行過濾
2.清理路由:
# 添加路由
await page.route("**/api/**", handler)
# 測試完成后移除
await page.unroute("**/api/**", handler)
3.錯誤處理:
async def safe_handler(route):
try:
await route.continue_()
except Exception as e:
print(f"Failed to handle {route.request.url}: {e}")
await route.abort()
4.性能敏感操作:
- 對于大量請求,考慮在 Python 端實(shí)現(xiàn)緩存
- 避免在路由處理器中進(jìn)行復(fù)雜計(jì)算
5.調(diào)試技巧:
# 打印未處理的請求
page.on("request", lambda r: print("Unhandled:", r.url))
Playwright 的網(wǎng)絡(luò)攔截 API 提供了對瀏覽器網(wǎng)絡(luò)活動的完全控制,使得測試復(fù)雜 web 應(yīng)用變得更加容易,特別是在需要模擬各種網(wǎng)絡(luò)條件或測試邊緣情況時。理解其底層原理有助于更有效地使用這些功能。
到此這篇關(guān)于Playwright實(shí)現(xiàn)網(wǎng)絡(luò)流量監(jiān)控與修改指南的文章就介紹到這了,更多相關(guān)Playwright網(wǎng)絡(luò)流量監(jiān)控內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何通過pycharm實(shí)現(xiàn)對數(shù)據(jù)庫的查詢等操作(非多步操作)
這篇文章主要介紹了如何通過pycharm實(shí)現(xiàn)對數(shù)據(jù)庫的查詢等操作(非多步操作),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
Python編寫電話薄實(shí)現(xiàn)增刪改查功能
這篇文章主要為大家詳細(xì)介紹了Python編寫電話薄實(shí)現(xiàn)增刪改查功能的相關(guān)資料,感興趣的朋友可以參考一下2016-05-05
Python實(shí)現(xiàn)自動管理PowerPoint幻燈片分節(jié)的方法
在處理包含大量幻燈片的 PowerPoint 演示文稿時,如何有效地組織和管理內(nèi)容成為一個重要挑戰(zhàn),本文將詳細(xì)介紹如何使用 Python 在 PowerPoint 中創(chuàng)建,刪除和管理節(jié)以及如何操作節(jié)內(nèi)的幻燈片,感興趣的小伙伴可以了解下2026-04-04
pycharm內(nèi)無法import已安裝的模塊問題解決
今天小編就為大家分享一篇pycharm內(nèi)無法import已安裝的模塊問題解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02

