如何在Puppeteer中等待空闲页面 控制并发标签页数量不超过上限
问题原因
你原来的代码存在两个核心问题:
Array.prototype.forEach不支持异步阻塞,传入的async回调会被同时触发,不会等待前一个回调执行完成再执行下一个,导致所有页面会在短时间内全部新建,并发控制完全失效。- 页面关闭逻辑放在迭代内部,可能出现部分任务还没启动浏览器就被关闭的问题,导致任务执行失败。
修正后的实现方案
const puppeteer = require('puppeteer'); // 最大同时打开的业务页面数量,可根据服务器限制调整 const MAX_CONCURRENT_PAGES = 10; let serialNumbers = ['FVFDT2GCQ6L7', 'DLXFG3X2DFJ1', 'FVFDT2GCQ6L7', 'DLXFG3X2DFJ1', 'FVFDT2GCQ6L7', 'DLXFG3X2DFJ1']; // 等待空闲页面的工具函数 async function waitForFreePage(browser) { while (true) { // browser.pages()默认包含1个启动时自带的空白标签页,总页面数=1+业务页面数 const currentPages = await browser.pages(); if (currentPages.length - 1 < MAX_CONCURRENT_PAGES) { // 存在空闲名额,退出等待 break; } // 无空闲页面,等待200ms后再次检查 await new Promise(resolve => setTimeout(resolve, 200)); } } async function processArray() { const browser = await puppeteer.launch({ headless: true }); // 存储所有任务的promise,用于最后统一等待所有任务完成 const taskPromises = []; // 替换forEach为支持异步阻塞的for...of循环 for (const item of serialNumbers) { // 新建页面前先等待空闲名额 await waitForFreePage(browser); // 启动当前串行号的处理任务 const task = (async () => { const page = await browser.newPage(); await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'); await page.goto(`https://support.apple.com/en_US/specs/${item}`); await page.waitForSelector('.article_link'); await page.click('.article_link'); await page.waitForSelector('#article'); const specs = await page.evaluate(() => { let article = document.querySelector('h1').innerHTML; return `${article}`; }); console.log(specs); await page.close(); })(); taskPromises.push(task); } // 等待所有串行号的处理任务全部完成 await Promise.all(taskPromises); // 所有任务完成后再关闭浏览器 await browser.close(); } processArray()
关键逻辑说明
- 替换
forEach为for...of循环:for...of支持await阻塞当前迭代,直到等待逻辑执行完成才会进入下一轮迭代,完美匹配需要控制并发的场景的需求。 - 空闲页等待逻辑:通过循环定期检查当前打开的页面数量,没有空闲名额时就暂停等待,保证同时运行的业务页面数量永远不会超过设定的阈值。
- 统一等待所有任务完成:通过
Promise.all收集所有任务的执行状态,所有任务跑完后再关闭浏览器,避免提前关闭浏览器导致未完成的任务报错。 - 并发阈值可配置:修改
MAX_CONCURRENT_PAGES常量可以根据实际服务器限制灵活调整最大并行数量。
内容的提问来源于stack exchange,提问作者Alexandr Kossykh
相关产品推荐
相关产品推荐

