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

如何将Selenium+Chrome DevTools拦截器改为线程化非阻塞形式并修复监听异常

解决方案

针对你需要线程化非阻塞拦截图片请求、修复事件监听不稳定的需求,以下是调整后的可行方案:

核心修改点

  • 将异步拦截逻辑封装到独立线程中,实现非阻塞运行
  • 优化事件处理逻辑,移除不必要的延迟,修正异常过滤规则
  • 调整启动顺序,确保拦截器在页面加载前就绪

修改后的完整代码

# Note: driver variable already initialized (Chrome)
import trio
import threading

def intercept(event, devtools):
    return devtools.fetch.fail_request(
        request_id=event.request_id,
        error_reason=devtools.network.ErrorReason.CONNECTION_REFUSED
    )

async def handle_requests(listener, connection, intercept_func):
    session, devtools = connection.session, connection.devtools
    async for event in listener:
        print({"frame_id": event.frame_id, "url": event.request.url})
        try:
            # 执行请求拦截操作
            await session.execute(intercept_func(event=event, devtools=devtools))
        except Exception as e:
            # 忽略已被处理的请求错误,避免无意义报错
            if "Request already handled" not in str(e):
                print(f"请求处理异常: {e}")

async def async_interceptor(pattern):
    async with driver.bidi_connection() as connection:
        session, devtools = connection.session, connection.devtools
        # 配置图片资源拦截规则
        request_pattern = devtools.fetch.RequestPattern.from_json(pattern)
        await session.execute(devtools.fetch.enable(patterns=[request_pattern]))
        
        # 监听所有暂停的请求事件
        request_listener = session.listen(devtools.fetch.RequestPaused)
        # 持续处理请求直到线程终止
        await handle_requests(request_listener, connection, intercept)

def start_interceptor():
    # 创建并启动拦截线程,设置为守护线程随主线程退出
    interceptor_thread = threading.Thread(
        target=trio.run,
        args=(async_interceptor, {"resourceType": "Image"}),
        daemon=True
    )
    interceptor_thread.start()
    return interceptor_thread

def main():
    # 先启动拦截器,确保拦截规则生效
    start_interceptor()
    # 加载目标页面
    driver.get("https://www.youtube.com/")
    # 保持主线程运行(可根据业务需求调整,比如等待页面元素加载完成)
    input("按回车键退出程序...")

if __name__ == "__main__":
    main()

关键说明

  1. 线程化实现:

    • 使用threading.Thread将异步拦截逻辑从主线程分离,通过daemon=True让拦截线程自动随主线程结束,无需手动管理
    • 主线程可以正常执行页面操作,不会被异步逻辑阻塞
  2. 修复监听不稳定问题:

    • 移除了原代码中冗余的await trio.sleep(0.0001),避免因延迟导致请求处理不及时
    • 优化异常处理逻辑,过滤掉"Request already handled"这类重复处理的常见错误,减少干扰
    • 拦截逻辑持续运行,能捕获页面初始加载及后续动态加载的所有图片请求
  3. 拦截规则优化:

    • 当前配置resourceType: "Image"会拦截所有图片类型资源,如果需要更精准的拦截,可以添加urlPattern参数,比如{"resourceType": "Image", "urlPattern": "*://*.youtube.com/*"}
    • 确保在页面加载前启动拦截器,避免初始请求漏拦截

内容的提问来源于stack exchange,提问作者kaliiiiiiiii

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 07:50:10