使用Puppeteer获取网络数据时遭遇UnhandledPromiseRejectionWarning问题
问题分析与解决方案
我来帮你排查下这个问题,你的代码里有几个关键问题导致了浏览器崩溃和未处理的Promise拒绝,咱们一步步来修正:
核心问题拆解
未处理的异步错误
你的自执行async函数没有错误捕获机制,一旦流程中出现Promise拒绝(比如页面加载失败、请求拦截出错),就会抛出UnhandledPromiseRejectionWarning,甚至直接导致进程崩溃。错误的响应体获取时机
在request事件中,你拿到的是请求对象(还没发送到服务器),这时候根本不存在响应体(response.body)。要获取返回的JSON数据,必须在response事件中处理——这是服务器返回响应后的回调时机。不合理的请求拦截逻辑
你现在的逻辑是直接终止所有非目标请求,但CNN主页加载需要依赖大量静态资源(CSS、JS、图片等),强行终止这些请求会导致页面加载异常,甚至让networkidle0的等待条件永远无法满足,最终触发Promise pending超时。
修正后的代码
(async () => { try { const browser = await puppeteer.launch({ headless: false, defaultViewport: null }); const page = await browser.newPage(); // 开启请求拦截 await page.setRequestInterception(true); page.on('request', (interceptedRequest) => { // 仅标记目标请求,不终止其他必要请求(保证页面正常加载) if (interceptedRequest.url().includes('cnni_homepage.json')) { console.log('已捕获目标JSON请求,等待响应...'); } interceptedRequest.continue(); }); // 在response事件中获取并解析JSON数据 page.on('response', async (response) => { if (response.url().includes('cnni_homepage.json') && response.ok()) { // 直接解析响应为JSON格式 const targetData = await response.json(); console.log('获取到的JSON数据:', targetData); // 这里可以添加你的数据处理逻辑(比如保存到本地、分析字段等) } }); // 导航到页面,用networkidle2替代networkidle0,避免等待过久 await page.goto("https://edition.cnn.com", { waitUntil: 'networkidle2' }); // 更精准的等待方式:直到目标响应完成 await page.waitForResponse(res => res.url().includes('cnni_homepage.json') && res.ok()); await browser.close(); } catch (error) { console.error('执行过程出错:', error); // 确保出错时浏览器能正常关闭 if (typeof browser !== 'undefined') { await browser.close(); } } })();
关键修改说明
- 添加
try/catch错误捕获:包裹整个异步流程,所有错误都会被捕获处理,避免未处理的Promise拒绝。 - 移到
response事件获取数据:这是唯一能拿到服务器返回响应体的时机,通过response.json()直接解析JSON内容。 - 调整请求拦截逻辑:不再终止非目标请求,保证页面能正常加载,同时精准标记目标请求。
- 使用
waitForResponse精准等待:替代固定延迟,确保目标JSON请求完成后再关闭浏览器,避免数据未获取到就结束流程。
这样修改后,你就能在浏览器加载页面时自动拦截并获取目标JSON的数据,完全不需要单独调用fetch,同时解决了崩溃和错误警告的问题。
内容的提问来源于stack exchange,提问作者ethanenglish
相关产品推荐
相关产品推荐

