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. 注意事项

  1. 必须处理请求:每个 handler 必须调用 continue_()fulfill() 或 abort(),否则请求会被挂起。

  2. 异步函数:处理函数需定义为 async def

  3. 作用域:路由仅对当前页面生效,页面跳转后需重新注册。

  4. 性能影响:频繁拦截可能影响测试速度,建议按需使用。

  5. 匹配顺序:多个路由按注册顺序匹配,第一个匹配的路由会处理请求。

7. 总结

  • 核心功能:通过 page.route(),你可以完全控制网络请求,这在测试和爬虫中非常有用。

  • 典型场景

    • 测试前端在不同 API 响应下的行为

    • 加速测试(屏蔽非必要资源)

    • 调试网络问题(记录请求日志)

  • Python 特有细节

    • 使用 continue_()(带下划线)

    • 处理函数必须是异步的(async def

    • 字符串匹配语法与 Python 正则表达式兼容

通过灵活使用 page.route(),你可以创建高度可控的浏览器自动化脚本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

测试开发Kevin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值