Vercel部署Express API时Puppeteer启动浏览器失败求助
Vercel部署Express API时Puppeteer启动失败的解决方案
问题背景
用Express开发REST API,构建阶段需通过Puppeteer爬取数据(不将爬取数据存入GitHub),但Vercel部署时触发错误:Error: Failed to launch the browser process!。尝试过Stack Overflow提到的sudo apt-get install装依赖的方案(但Vercel仅支持npm包),以及chrome-aws-lambda+puppeteer-core的方案,均未解决问题。
构建命令:node scrap.js && node index.js
原爬取代码(存在语法错误):
const fs = require("fs"); onst fs = require("fs"); // 拼写错误+重复引入 let chrome = {}; let puppeteer; if (process.env.AWS_LAMBDA_FUNCTION_VERSION) { chrome = require("chrome-aws-lambda"); puppeteer = require("puppeteer-core"); } else { puppeteer = require("puppeteer"); } const writeIconFile = (name, content) => { fs.appendFile(name, content, (err) => { if (err) throw err; }); }; const scrap = async () => { let options = {}; if (process.env.AWS_LAMBDA_FUNCTION_VERSION) { options = { args: [...chrome.args, "--hide-scrollbars", "--disable-web-security"], defaultViewport: chrome.defaultViewport, executablePath: await chrome.executablePath, headless: true, ignoreHTTPSErrors: true, }; } let data; try { let browser = await puppeteer.launch(options); let page = await browser.newPage(); await page.goto("https://www.google.com"); data = await page.title(); } catch (err) { console.error(err); data = null; } return data; }; scrap().then((data) => { writeIconFile("data.txt", data); });
核心问题
- 环境判断错误:Vercel构建阶段不会触发
AWS_LAMBDA_FUNCTION_VERSION变量,代码未进入适配逻辑。 - 语法错误:重复引入
fs、onst拼写错误。 - 构建阶段文件存储无效:Vercel构建完成后会清理临时文件,
data.txt无法在运行阶段读取。 - 启动参数不足:缺少Vercel无特权环境必需的浏览器启动参数。
修正方案
1. 修复代码语法错误
删除重复的fs引入,修正拼写错误:
const fs = require("fs"); let chrome = {}; let puppeteer;
2. 适配Vercel环境判断
同时判断Vercel构建和运行阶段的环境变量:
const isVercelEnv = process.env.VERCEL === "1" || process.env.AWS_LAMBDA_FUNCTION_VERSION; if (isVercelEnv) { chrome = require("chrome-aws-lambda"); puppeteer = require("puppeteer-core"); } else { puppeteer = require("puppeteer"); }
3. 补充浏览器启动参数
添加Vercel环境必需的参数,避免权限和内存问题:
const scrap = async () => { let options = {}; const isVercelEnv = process.env.VERCEL === "1" || process.env.AWS_LAMBDA_FUNCTION_VERSION; if (isVercelEnv) { options = { args: [ ...chrome.args, "--hide-scrollbars", "--disable-web-security", "--disable-dev-shm-usage", // 解决容器内存限制 "--no-sandbox", // 无特权环境强制开启 "--single-process" // 降低资源占用 ], defaultViewport: chrome.defaultViewport, executablePath: await chrome.executablePath, headless: "new", // 使用新版无头模式,兼容性更好 ignoreHTTPSErrors: true, handleSIGINT: false // 避免构建中断时的异常 }; } let data; try { const browser = await puppeteer.launch(options); const page = await browser.newPage(); await page.goto("https://www.google.com"); data = await page.title(); await browser.close(); // 必须关闭浏览器,避免资源泄漏 } catch (err) { console.error(err); data = null; } return data; };
4. 调整数据存储方式
将爬取数据嵌入代码模块(而非txt文件),确保运行阶段可访问:
scrap().then((data) => { // 生成可导入的JS模块 fs.writeFile( "./scraped-data.js", `module.exports = ${JSON.stringify(data)};`, (err) => { if (err) throw err; console.log("爬取数据已写入模块"); } ); });
在Express中引入数据:
const scrapedData = require('./scraped-data.js');
5. 更新依赖与构建命令
在package.json中添加必要依赖:
{ "dependencies": { "express": "^4.18.2", "chrome-aws-lambda": "^10.1.0", "puppeteer-core": "^21.0.0", "puppeteer": "^21.0.0" // 本地开发使用 } }
构建命令修改为:
npm install && node scrap.js && node index.js
验证步骤
- 本地运行修正后的代码,确认爬取功能正常。
- 推送代码至GitHub,触发Vercel自动部署。
- 查看Vercel构建日志,确认Puppeteer启动成功且数据生成正常。
内容的提问来源于stack exchange,提问作者arnaudpf
相关产品推荐
相关产品推荐

