使用Puppeteer爬取时,如何获取表单提交后新打开页面的内容?
问题分析与解决方案
你的代码卡住的核心原因有两个:
- Promise.all 使用错误:你在数组内给每个操作都加了
await,这会让每个操作先执行完毕再传入数组,完全违背了Promise.all并行执行的设计逻辑,同时导致waitForNavigation提前进入无意义的等待状态。 - 错误调用waitForNavigation:Command+Click触发的是新页面打开,当前页面并未发生导航行为,而你设置了
timeout:0,导致waitForNavigation会无限等待,直接卡死后续代码。
修正后的代码
console.log('before new page'); // 监听浏览器的新页面创建事件,捕获Command+Click打开的新窗口 const newPagePromise = new Promise(resolve => browser.once('targetcreated', target => resolve(target.page()))); // 依次执行操作:阻止右键菜单冒泡、按下Command键、点击提交按钮、松开Command键 await page.evaluate(() => { document.addEventListener( 'contextmenu', (event) => event.stopPropagation(), true ); }); await page.keyboard.down('Meta'); await page.click('input[type="submit"][name="formsearch"]'); await page.keyboard.up('Meta'); // 等待新页面加载完成 const newPage = await newPagePromise; await newPage.waitForLoadState('networkidle'); // 确保页面资源加载完毕 console.log('after new page'); console.log('New page URL: ' + newPage.url()); console.log('All browser pages: ', await browser.pages());
关键说明
- 用
browser.once('targetcreated')监听新页面创建:Command+Click打开的新窗口属于浏览器的新target,这个事件能精准捕获到新页面实例。 - 移除Promise.all内的
await:这里的操作有先后依赖(按键→点击→松键),不需要并行执行,按顺序调用await即可。 - 用
waitForLoadState等待新页面加载:确保新页面的DOM和资源都加载完成后,再去获取页面内容。
内容的提问来源于stack exchange,提问作者Harsh Divate
相关产品推荐
相关产品推荐

