You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 09:35:23