调用browser.close()后Puppeteer进程仍无法终止的解决咨询
解决Puppeteer脚本执行后进程无限运行的问题
核心问题分析
你的脚本中存在几个导致进程无法正常退出的关键问题:
- 重复调用
browser.close(),且在强制终止浏览器进程后再次执行关闭操作,引发资源释放异常 proxy-chain的anonymizeProxy会启动本地代理服务器,若未手动关闭,会持续占用进程资源- Puppeteer Extra插件可能持有未完成的异步任务,阻止Node.js进程退出
具体修复方案
1. 清理重复的浏览器关闭逻辑
移除finally块中重复的browser.close()调用,调整关闭顺序,仅在必要时强制终止浏览器进程。
2. 手动关闭proxy-chain代理服务器
anonymizeProxy创建的本地代理需要调用closeAnonymizedProxy()方法主动终止,否则会一直运行导致进程无法退出。
3. 兜底强制退出Node.js进程
在所有资源清理完成后,明确调用process.exit()确保进程彻底终止。
修复后的完整代码
import puppeteer from "puppeteer-extra"; import RecaptchaPlugin from "puppeteer-extra-plugin-recaptcha"; import { executablePath } from "puppeteer"; import { anonymizeProxy, closeAnonymizedProxy } from "proxy-chain"; async function main() { console.log("Starting ..."); let newProxyUrl = null; let browser = null; try { const proxy = "http://XXXXXXXXXXXXXXXXXXXXXX"; newProxyUrl = await anonymizeProxy(proxy); puppeteer.use( RecaptchaPlugin({ provider: { id: "2captcha", token: "XXXXXXXXXXXXXXXXXX", }, }) ); browser = await puppeteer.launch({ headless: true, executablePath: executablePath(), args: [ "--no-zygote", "--no-sandbox", `--proxy-server=${newProxyUrl}`, ], }); const page = await browser.newPage(); await page.setDefaultNavigationTimeout(180000); await page.goto("http://www.example.com"); // 执行其他业务逻辑 console.log("Closing the page"); await page.close(); console.log("Closed the page"); await browser.close(); console.log("Closed the browser"); // 仅在浏览器进程未终止时强制杀死 const browserProcess = browser.process(); if (browserProcess && !browserProcess.killed) { browserProcess.kill("SIGINT"); console.log("Force closed the browser process"); } } catch (error) { console.error("Error occurred:", error); // 异常场景下确保浏览器关闭 if (browser) { await browser.close().catch(err => console.error("Failed to close browser:", err)); } } finally { // 关闭proxy-chain创建的代理服务器 if (newProxyUrl) { await closeAnonymizedProxy(newProxyUrl, true).catch(err => console.error("Failed to close proxy:", err)); console.log("Closed proxy server"); } // 强制退出Node.js进程 process.exit(0); } } main().catch(err => { console.error("Unhandled error:", err); process.exit(1); });
额外优化建议
- 移除
--single-process参数:该参数会让Chrome在单个进程中运行,容易引发资源释放不彻底的问题 - 检查Recaptcha插件任务:确保验证码处理的所有异步任务已完成,避免残留操作阻止进程退出
- 捕获所有未处理异常:通过
main().catch()捕获顶层异常,避免未处理错误导致进程挂起
内容的提问来源于stack exchange,提问作者Indrajeet Haldar
相关产品推荐
相关产品推荐

