如何将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()
关键说明
线程化实现:
- 使用
threading.Thread将异步拦截逻辑从主线程分离,通过daemon=True让拦截线程自动随主线程结束,无需手动管理 - 主线程可以正常执行页面操作,不会被异步逻辑阻塞
- 使用
修复监听不稳定问题:
- 移除了原代码中冗余的
await trio.sleep(0.0001),避免因延迟导致请求处理不及时 - 优化异常处理逻辑,过滤掉"Request already handled"这类重复处理的常见错误,减少干扰
- 拦截逻辑持续运行,能捕获页面初始加载及后续动态加载的所有图片请求
- 移除了原代码中冗余的
拦截规则优化:
- 当前配置
resourceType: "Image"会拦截所有图片类型资源,如果需要更精准的拦截,可以添加urlPattern参数,比如{"resourceType": "Image", "urlPattern": "*://*.youtube.com/*"} - 确保在页面加载前启动拦截器,避免初始请求漏拦截
- 当前配置
内容的提问来源于stack exchange,提问作者kaliiiiiiiii
相关产品推荐
相关产品推荐

