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

使用Lambda函数+Puppeteer-Stealth启动Chromium时遇spawn ETXTBSY错误

Puppeteer在Lambda上运行出现spawn ETXTBSY错误排查

问题描述

本地运行Puppeteer网页爬取代码正常,但上传为AWS Lambda函数后出现spawn ETXTBSY错误,错误截图如下:
错误截图

我的代码

let browser = null;
try {
  puppeteerExtra.use(StealthPlugin());
  browser = await puppeteerExtra.launch({
    args: chromium.args,
    defaultViewport: chromium.defaultViewport,
    executablePath: await chromium.executablePath(),
    headless: "new",
  });
  const page = await browser.newPage();
  await page.setViewport({
    width: 1620,
    height: 900,
  });
  await page.goto(NEWS_PAGE_URL, {
    timeout: 18900000,
  });

  console.log("open");

  await page.evaluate(() => {
    const acceptButton = document.querySelector(".accept-all");
    acceptButton.click();
  });
  console.log("open");
  const pages = await browser.pages();

  await page.waitForNavigation({ waitUntil: "domcontentloaded" });
  console.log("open");
  let originalOffset = 0;
  while (true) {
    await page.evaluate("window.scrollBy(0, document.body.scrollHeight)");
    await page.waitForTimeout(500);
    let newOffset = await page.evaluate("window.pageYOffset");
    if (originalOffset === newOffset) {
      break;
    }
    originalOffset = newOffset;
  }
  await page.waitForTimeout(1000);
  console.log("open");
  const pageContent = await page.content();
  // console.log(pageContent);
  await pages[0].close();
  await pages[1].close();

  await browser.close();
}

package.json配置

{
  "name": "parser",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@sparticuz/chromium": "^116.0.0",
    "aws-sdk": "^2.1441.0",
    "axios": "^1.4.0",
    "cheerio": "^1.0.0-rc.12",
    "chrome-aws-lambda": "^10.1.0",
    "dotenv": "^16.3.1",
    "puppeteer": "^21.1.0",
    "puppeteer-core": "^21.1.0",
    "puppeteer-extra": "^3.3.6",
    "puppeteer-extra-plugin-stealth": "^211.2"
  }
}

我曾尝试使用chrome-aws-lambda的相关方案,但错误依旧,请问问题出在哪?怎么解决?


问题原因及解决方案

1. 依赖冲突与版本不匹配

你的package.json同时安装了@sparticuz/chromium和chrome-aws-lambda,这两个包都是为Lambda提供Chromium运行环境的,同时存在会引发资源竞争,导致ETXTBSY(文本文件忙)错误。另外,Puppeteer 21.1.0对应Chromium 118,而@sparticuz/chromium 116.0.0版本不兼容,这也是启动失败的核心原因。

解决步骤:

  • 删除chrome-aws-lambda依赖,保留@sparticuz/chromium(它是chrome-aws-lambda的官方维护续作)
  • 将@sparticuz/chromium升级到118.x版本,与Puppeteer 21.1.0匹配
  • 移除完整的puppeteer包,只保留puppeteer-core(Lambda环境不需要本地Chromium,puppeteer-core更轻量)

修改后的依赖部分:

"dependencies": {
  "@sparticuz/chromium": "^118.0.0",
  "aws-sdk": "^2.1441.0",
  "axios": "^1.4.0",
  "cheerio": "^1.0.0-rc.12",
  "dotenv": "^16.3.1",
  "puppeteer-core": "^21.1.0",
  "puppeteer-extra": "^3.3.6",
  "puppeteer-extra-plugin-stealth": "^211.2"
}

2. Lambda文件系统权限与路径配置

ETXTBSY错误也可能是Chromium可执行文件权限不足,或Lambda唯一可写目录/tmp被占用导致。调整启动参数,强制将Chromium的缓存、用户数据等目录指向/tmp:

browser = await puppeteerExtra.launch({
  args: [
    ...chromium.args,
    "--no-sandbox",
    "--disable-setuid-sandbox",
    "--disable-dev-shm-usage",
    "--single-process",
    "--user-data-dir=/tmp/user-data",
    "--data-path=/tmp/data-path",
    "--disk-cache-dir=/tmp/cache-dir"
  ],
  defaultViewport: chromium.defaultViewport,
  executablePath: await chromium.executablePath(),
  headless: "new",
  ignoreHTTPSErrors: true,
});

3. 资源释放逻辑错误

代码中手动关闭pages[0]和pages[1]可能导致浏览器进程异常,建议直接关闭整个浏览器以确保资源彻底释放:

// 移除这两行手动关闭页面的代码
// await pages[0].close();
// await pages[1].close();

// 只保留浏览器关闭逻辑
await browser.close();

4. 部署包大小超限

如果安装了完整puppeteer包,会包含本地Chromium二进制文件,导致部署包过大(Lambda限制未压缩50MB、压缩250MB),解压时触发错误。确保只使用puppeteer-core,并通过npm install --production安装依赖,避免不必要的开发包。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:47:24