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的已知缺陷,为代码编写错误导致,核心问题如下:
- 参数格式完全不符合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 )) - 同类方法异常原因一致
get_response_body、fulfill_request出现相同挂起问题,均为传参不符合CDP接口规范导致:例如fulfill_request需要传入符合格式要求的响应状态码、响应头、响应体内容,传入非法格式或自定义无效值时,CDP服务端不会返回合法响应,请求会持续保持pending状态。 - 代码冗余与异常吞没有助于放大问题
- 代码中创建的
trio.open_nursery()上下文没有放入任何异步任务,属于冗余写法,本身不影响逻辑但可以删除简化代码。 - 代码使用裸
except直接吞掉了CDP调用抛出的参数非法异常,导致无法在控制台看到明确的参数错误提示,容易误判为方法本身存在缺陷。调试时建议打印异常栈信息,可以快速定位参数不匹配问题。
- 代码中创建的
修复时注意:Selenium 4.3.0的BiDi连接会自动根据当前连接的Chrome大版本加载对应版本的CDP协议定义,不需要手动拼接JSON结构传参,直接使用
connection.devtools下自动生成的枚举类、数据类构造参数即可,避免出现格式错误。
内容的提问来源于stack exchange,提问作者D.Angelov
相关产品推荐
相关产品推荐

