You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium4 Python调用CDP fetch.fail_request请求挂起未生效问题

问题说明

使用Selenium BiDi连接调用Chrome DevTools Protocol(CDP)Fetch域方法做请求拦截时,fetch.fail_request 无法让匹配的目标请求触发失败,仅会将请求持续保持为pending挂起状态;调用get_response_body、fulfill_request 方法时存在相同异常。所有通过continue_request方法放行的请求运行正常,无异常。
代码中导入的GeneralFunctions模块用于返回带预定义操作配置的driver对象,导入的testSetup模块用于提供通用变量访问入口。

运行环境信息
  • Python 版本:3.10
  • Selenium webdriver 版本:4.3.0
  • Webdriver-manager 版本:3.8.0(用于下载匹配版本的Chrome驱动)
  • Trio 版本:0.20.0
  • Chrome 浏览器版本:103
复现代码
import trio
import time
from Setup.Setup import testSetup
from Setup.General import GeneralFunctions
from selenium.webdriver.common.by import By
generalFunctions = GeneralFunctions()
async def main1():
    driver = generalFunctions.newChrome(testSetup.url)
    time.sleep(6)
    async with driver.bidi_connection() as connection:        
        session, devtools = connection.session, connection.devtools
        await session.execute(devtools.fetch.enable())
        listener = session.listen(devtools.fetch.RequestPaused)
        async with trio.open_nursery() as nursery:
            driver.refresh()
            async for event in listener:
                if "userData" in str(event.request.url) and event.request.method == "GET":
                    try:
                         await session.execute(devtools.fetch.fail_request(event.request_id, '{"error_reason": "aaaa"}'))
                        
                    except:
                        print("problem with target request")
                else:
                    try:
                        await session.execute(devtools.fetch.continue_request(event.request_id))
                    except:
                        print("problem with regular request")


async def main2():
    await main1()


trio.run(main2)
问题原因与修复方法

该问题不属于Python环境下Selenium的已知缺陷,为代码编写错误导致,核心问题如下:

  1. 参数格式完全不符合CDP接口要求
    devtools.fetch.fail_request 方法的第二个参数error_reason不需要传入JSON字符串,Selenium封装的CDP客户端会自动处理序列化,直接传入对应CDP版本定义的错误枚举值即可。当前代码传入自定义拼接的JSON字符串'{"error_reason": "aaaa"}',且aaaa不属于CDP规范中定义的合法错误原因枚举值,CDP服务端无法识别该参数,不会执行请求失败逻辑,最终导致请求一直处于暂停挂起状态。
    合法的错误原因需使用CDP规定的枚举值,例如Failed、Aborted、ConnectionReset等,正确调用示例:
    # 导入当前Chrome版本对应的CDP定义,Chrome 103对应v103版本
    from selenium.webdriver.common.devtools.v103 import network
    # 调用fail_request
    await session.execute(devtools.fetch.fail_request(
        request_id=event.request_id,
        error_reason=network.ErrorReason.FAILED
    ))
    
  2. 同类方法异常原因一致
    get_response_body、fulfill_request 出现相同挂起问题,均为传参不符合CDP接口规范导致:例如fulfill_request需要传入符合格式要求的响应状态码、响应头、响应体内容,传入非法格式或自定义无效值时,CDP服务端不会返回合法响应,请求会持续保持pending状态。
  3. 代码冗余与异常吞没有助于放大问题
    • 代码中创建的trio.open_nursery()上下文没有放入任何异步任务,属于冗余写法,本身不影响逻辑但可以删除简化代码。
    • 代码使用裸except直接吞掉了CDP调用抛出的参数非法异常,导致无法在控制台看到明确的参数错误提示,容易误判为方法本身存在缺陷。调试时建议打印异常栈信息,可以快速定位参数不匹配问题。

修复时注意:Selenium 4.3.0的BiDi连接会自动根据当前连接的Chrome大版本加载对应版本的CDP协议定义,不需要手动拼接JSON结构传参,直接使用connection.devtools下自动生成的枚举类、数据类构造参数即可,避免出现格式错误。

内容的提问来源于stack exchange,提问作者D.Angelov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:15:11