playwright的高级应用技巧之通过page.route修改请求过滤资源
在实际工作里我们可以在Playwright 的无头模式中通过过滤网页响应的资源类型(例如:过滤图片)来阻止图片资源的加载进而提升测试执行效率。通过Playwright 的page.route() API可以拦截和修改网络请求和响应。它允许你在浏览器页面发送请求时进行干预,从而实现模拟数据、屏蔽资源、修改请求头等功能。
1. 核心概念
-
作用:通过 URL 匹配规则拦截请求,然后对请求或响应进行修改。
-
适用场景:
-
模拟 API 响应(如返回假数据)
-
屏蔽广告或跟踪脚本
-
修改请求头(如添加认证信息)
-
记录网络请求日志
-
加速测试(如阻止加载图片、CSS 等非必要资源)
-
2. 基本语法(Python)
await page.route(url_pattern, handler)
-
参数说明:
-
url_pattern:匹配请求 URL 的规则,可以是字符串、正则表达式或函数。 -
handler:处理函数,需接收route和request两个参数,并决定如何处理请求。
-
3. 处理函数的关键操作
在 handler 中,必须调用以下方法之一:
a. 继续请求(可修改请求)
await route.continue_(
url="https://new-url.com",
method="POST",
headers={"User-Agent": "Mozilla/5.0"},
post_data=b"binary_data"
)
-
continue_方法(注意下划线,因为continue是 Python 关键字)
b. 返回自定义响应
await route.fulfill(
status=200,
content_type="text/html",
body="<h1>Mock Response</h1>",
headers={"Cache-Control": "no-cache"}
)
-
直接返回模拟数据,不发送实际请求。
c. 中止请求
await route.abort() # 默认中止类型为 "failed"
# 或指定原因
await route.abort("blockedbyclient")
-
中止类型包括
"aborted","accessdenied","blockedbyclient"等。
4. Python 示例
示例 1:模拟 API 响应
async def handle_route(route, request):
if "/api/user" in request.url:
await route.fulfill(
status=200,
content_type="application/json",
body=json.dumps({"id": 1, "name": "Mock User"})
)
else:
await route.continue_()
await page.route("**/api/**", handle_route)
示例 2:屏蔽图片和 CSS
async def block_resources(route, request):
if request.resource_type in ["image", "stylesheet"]:
await route.abort()
else:
await route.continue_()
await page.route("**/*", block_resources)
示例 3:修改请求头
async def add_auth_header(route, request):
headers = request.headers.copy()
headers["Authorization"] = "Bearer fake-token"
await route.continue_(headers=headers)
await page.route("**/api/**", add_auth_header)
5. 高级用法
动态 URL 匹配
使用函数判断复杂条件:
def url_matcher(request):
return "tracking" in request.url and request.resource_type == "script"
async def block_tracking(route, request):
await route.abort()
await page.route(url_matcher, block_tracking)
修改响应内容
async def modify_response(route, request):
# 先获取原始响应
response = await route.fetch()
body = await response.text()
modified_body = body.replace("Original Text", "Replaced Text")
await route.fulfill(response=response, body=modified_body)
await page.route("https://example.com/data.json", modify_response)
取消路由注册
# 注册路由
await page.route("**/ads/**", lambda route, _: route.abort())
# 取消路由
await page.unroute("**/ads/**")
6. 注意事项
-
必须处理请求:每个
handler必须调用continue_(),fulfill()或abort(),否则请求会被挂起。 -
异步函数:处理函数需定义为
async def。 -
作用域:路由仅对当前页面生效,页面跳转后需重新注册。
-
性能影响:频繁拦截可能影响测试速度,建议按需使用。
-
匹配顺序:多个路由按注册顺序匹配,第一个匹配的路由会处理请求。
7. 总结
-
核心功能:通过
page.route(),你可以完全控制网络请求,这在测试和爬虫中非常有用。 -
典型场景:
-
测试前端在不同 API 响应下的行为
-
加速测试(屏蔽非必要资源)
-
调试网络问题(记录请求日志)
-
-
Python 特有细节:
-
使用
continue_()(带下划线) -
处理函数必须是异步的(
async def) -
字符串匹配语法与 Python 正则表达式兼容
-
通过灵活使用 page.route(),你可以创建高度可控的浏览器自动化脚本。
更多推荐



所有评论(0)