Pyppeteer捕获指定请求头后如何关闭浏览器并停止asyncio事件循环
解决Pyppeteer捕获到指定请求头后无法关闭浏览器退出的问题
问题原因
- 原代码使用同步的
time.sleep(10000)会阻塞整个asyncio事件循环,即使匹配到请求头也无法执行后续退出逻辑 - 拦截请求的回调协程和主协程没有通信通道,无法通知主协程终止运行
解决方法
用asyncio内置的Event作为终止信号,在拦截函数匹配到目标请求头后触发信号,通知主协程直接关闭浏览器退出,替换掉无意义的长时间sleep。
修改后完整代码:
import asyncio from pyppeteer import launch async def main(): browser = await launch(headless=False, autoclose=False) page = await browser.newPage() # 创建终止信号事件 exit_event = asyncio.Event() async def intercept_network_requests(request): # 先放行请求,避免页面加载卡住 await request.continue_() for key in request.headers: if 'some_header_name' in key: print('Got header value: ', request.headers[key]) # 关闭浏览器 await browser.close() # 触发终止信号 exit_event.set() page.on('request', lambda request: asyncio.ensure_future(intercept_network_requests(request))) await page.goto('https://example.com') # 等待终止信号触发,替代原来的同步sleep await exit_event.wait() asyncio.get_event_loop().run_until_complete(main())
逻辑说明
- 主协程中创建
asyncio.Event实例,作为终止运行的通知信号 - 拦截函数直接复用main作用域中的browser和event变量,匹配到目标请求头时先关闭浏览器,再触发信号
- 用
await event.wait()替代同步的time.sleep,该方法是非阻塞的,一旦收到信号就会立刻向下执行,结束脚本 - 调用
await request.continue_()保证所有请求正常放行,不会导致页面加载卡住
内容的提问来源于stack exchange,提问作者Pejko
相关产品推荐
相关产品推荐

