使用Puppeteer点击「加载更多」后拦截后续XHR请求的问题
解决Puppeteer拦截点击后XHR请求的问题
核心问题
你的代码在点击「加载更多」后立刻关闭了浏览器,此时新的请求还没来得及触发或被捕获;另外request事件回调里不该放置DOM操作代码,会阻塞请求处理流程。
修正后的代码方案
方案一:通过请求计数等待
const grab = async(url) => { const browser = await puppeteer.launch({ headless: false}); const page = await browser.newPage(); // 统计捕获到的目标请求数 let capturedCount = 0; // 预期总请求数:初始2个 + 点击后1个 const totalExpected = 3; await page.setRequestInterception(true); page.on("request", (request) => { const reqUrl = request.url(); if (reqUrl.includes('betty-variants')) { console.log(reqUrl); capturedCount++; } request.continue(); // 此方法无需await,同步执行即可 }); await page.goto(url, { waitUntil: 'networkidle2' }); // 等待按钮渲染并点击 await page.waitForSelector('.well-sm.well p.text-primary.pull-left span'); await page.click('.well-sm.well p.text-primary.pull-left span'); // 等待捕获到预期数量的请求,超时时间设为10秒 await page.waitForFunction( (targetCount) => window.capturedCount >= targetCount, { timeout: 10000 }, { capturedCount } ); await browser.close(); };
方案二:通过Promise监听特定请求
如果能识别点击后请求的独有特征,可直接监听该请求完成:
const grab = async(url) => { const browser = await puppeteer.launch({ headless: false}); const page = await browser.newPage(); await page.setRequestInterception(true); // 创建Promise等待点击后的目标请求 const waitForLoadMoreRequest = new Promise(resolve => { page.on("request", (request) => { const reqUrl = request.url(); if (reqUrl.includes('betty-variants')) { console.log(reqUrl); // 这里可添加点击后请求的独有特征判断,比如特定参数 if (reqUrl.includes('load-more-specific-param')) { resolve(); } } request.continue(); }); }); await page.goto(url, { waitUntil: 'networkidle2' }); await page.waitForSelector('.well-sm.well p.text-primary.pull-left span'); await page.click('.well-sm.well p.text-primary.pull-left span'); // 等待目标请求触发 await waitForLoadMoreRequest; await browser.close(); };
关键调整点
- 移除
request事件内的DOM操作:该回调仅用于处理请求拦截逻辑,DOM操作需放在页面加载完成后单独执行。 - 增加等待逻辑:点击按钮后必须等待新请求触发并被捕获,不能直接关闭浏览器,可通过计数或特征监听实现。
- 修正
request.continue()的使用:此方法为同步执行,无需添加await。
内容的提问来源于stack exchange,提问作者Artem Taran
相关产品推荐
相关产品推荐

