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

如何在Puppeteer中定时截图后正常关闭浏览器避免僵尸进程?

问题分析

问题出在getScreenshots的实现逻辑上:当执行resolve(promises)返回结果时,数组中的截图Promise可能还处于Pending状态(截图操作尚未完成),此时await getScreenshots会直接进入后续流程,finally块关闭浏览器时,正在执行的截图操作会因为浏览器实例被销毁而抛出错误。

解决方案

修改getScreenshots,确保所有截图操作完成后再返回结果;同时在合适时机关闭页面,避免资源泄漏。

改写后的完整代码

const getScreenshots = async (browser, url, ms, frames): Promise<string[]> => {
  const page = await browser.newPage()
  await page.setViewport({ width: 1280, height: 800 })

  await page.goto(url, {
    waitUntil: "networkidle0",
  })

  const promises: Promise<string>[] = []
  return new Promise((resolve) => {
    const intervalId = setInterval(() => {
      // 将截图Promise存入数组
      promises.push(
        page.screenshot({
          captureBeyondViewport: true,
          fullPage: true,
          encoding: "base64",
        })
      )
      
      if (promises.length >= frames) {
        clearInterval(intervalId)
        // 等待所有截图Promise完成后再返回结果,同时关闭页面
        Promise.all(promises)
          .then(async (results) => {
            await page.close()
            resolve(results)
          })
      }
    }, ms)
  })
}

const screenshotTest = async (url: string): Promise<string> => {
  const browser = await puppeteer.launch({ timeout: 100000 })
  try {
    const imgArray = await getScreenshots(browser, url, 42, 24)
    return imgArray[imgArray.length - 1]
  } finally {
    await browser.close()
  }
}

关键修改点

  • 等待所有截图完成:将resolve(promises)改为Promise.all(promises).then(...),确保所有异步截图操作执行完毕后才返回结果,此时await getScreenshots会等待所有截图完成,再进入finally块关闭浏览器。
  • 及时关闭页面:在所有截图完成后关闭页面page.close(),避免页面实例占用资源。
  • 类型优化:移除了imgArray: any[]的冗余类型声明,让TypeScript自动推导类型更严谨。

这样修改后,既不会出现僵尸进程,也不会因为提前关闭浏览器导致截图失败。

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 02:17:44