Node.js与Puppeteer代理超时错误求助:重启函数无效
解决方案:处理Puppeteer代理超时并自动重启切换代理
原代码存在的问题
- 调用异步函数
getPic()时未加await,导致错误无法被try-catch捕获 catch块变量名错误(定义的是c却使用error)- 代理列表仅包含一个代理,无法切换可用节点
- 代码存在语法错误:
puppeteer.launch配置项缺逗号、awaitpage拼写错误、console log应为console.log - 未处理浏览器资源泄漏(报错时未关闭浏览器)
setInterval与递归重启逻辑冲突,可能导致重复执行
修正后的完整代码
const puppeteer = require('puppeteer'); const proxyChain = require('proxy chain'); // 扩展代理列表,添加多个可用代理 const proxiesList = [ 'http://208.70.77.222:1994', // 这里添加更多代理地址 'http://xxx.xxx.xxx.xxx:xxxx', 'http://yyy.yyy.yyy.yyy:yyyy' ]; async function getPic() { let browser = null; try { // 随机选择一个代理 const oldProxyUrl = proxiesList[Math.floor(Math.random() * proxiesList.length)]; const newProxyUrl = await proxyChain.anonymizeProxy(oldProxyUrl); browser = await puppeteer.launch({ headless: false, ignoreHTTPSErrors: true, args: [ `--proxy-server=${newProxyUrl}`, `--ignore-certificate-errors`, `--no-sandbox`, `--disable-setuid-sandbox` ] }); const page = await browser.newPage(); await page.setUserAgent('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.43 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36OPR/94.0.0.0'); await page.goto('https://siteURL.com/', { waitUntil: "domcontentloaded", timeout: 30000 // 设置超时时间,避免无限等待 }); await page.waitForSelector('input[type="search"]', { timeout: 15000 }); await page.type('input[type="search"]', 'pc programs', { delay: 500 }); await page.click('button[type="submit"]'); await page.waitForSelector('.footer-wrap', { timeout: 15000 }); // 滚动页面 await page.evaluate(() => new Promise((resolve) => { let scrollTop = -1; const interval = setInterval(() => { window.scrollBy(0, 100); if (document.documentElement.scrollTop !== scrollTop) { scrollTop = document.documentElement.scrollTop; return; } clearInterval(interval); resolve(); }, 500); })); await page.screenshot({ path: 'scr.png' }); console.log('任务执行成功'); } catch (error) { console.error(`执行失败: ${error.message}`); // 抛出错误让上层重试逻辑处理 throw error; } finally { // 确保浏览器无论成功失败都关闭,避免资源泄漏 if (browser) { await browser.close(); } } } // 带重试逻辑的启动函数 async function startWithRetry() { try { await getPic(); // 任务成功后,等待50秒再执行下一次 setTimeout(startWithRetry, 50000); } catch (error) { // 捕获超时或代理相关错误 if (error.message.includes('ERR_TIMED_OUT') || error.message.includes('proxy')) { console.log('代理异常,5秒后重试...'); setTimeout(startWithRetry, 5000); } else { // 其他错误抛出,避免无限重试 console.error('遇到非代理类错误:', error); throw error; } } } // 启动程序 startWithRetry();
关键改进点
- 完善错误捕获:在
getPic内部添加try-catch-finally,确保浏览器资源被正确释放,同时将错误抛出给上层重试逻辑 - 修复语法错误:修正配置项逗号、拼写错误等问题
- 扩展代理池:提供多个代理节点,错误时随机切换新代理
- 设置超时时间:为
page.goto和waitForSelector添加超时,避免无限等待 - 替换setInterval为递归调用:避免定时器与重试逻辑冲突,保证每次任务完成(或失败重试)后再执行下一次
- 精准错误判断:通过判断错误信息中的关键词,只对代理/超时错误进行重试
内容的提问来源于stack exchange,提问作者Юрий Веселов
相关产品推荐
相关产品推荐

