在AWS Lambda中用Puppeteer+Chromium爬取网页遇浏览器断开错误求助
解决AWS Lambda中Puppeteer + Chromium导航失败(浏览器断开)的问题
以下是针对性的排查和修复方案:
核心问题修复
1. 修正Chromium无头模式设置
原代码中chromium.setHeadlessMode = true;是错误的赋值写法,正确方式是调用方法:
chromium.setHeadlessMode(true);
错误的设置会导致浏览器启动参数异常,直接引发断开问题。
2. 提升Lambda资源配置
Chromium对内存和运行时间要求较高:
- 将Lambda内存调整为1024MB以上(推荐1536MB),内存不足会直接导致Chromium崩溃
- 将Lambda超时时间设置为30秒以上(最长可设15分钟),避免因页面加载超时间接触发浏览器断开
3. 优化页面导航等待策略
waitUntil: "networkidle0"要求网络完全空闲,部分网页的长连接(如WebSocket)会导致无限等待,可替换为更宽松的策略:
await page.goto(url, { waitUntil: "networkidle2" });
或选择DOM加载完成即触发:
await page.goto(url, { waitUntil: "domcontentloaded" });
4. 修复内容提取循环逻辑
原循环会不断覆盖content变量,仅保留最后一个选择器的结果,找到内容后应立即终止循环:
for (let selector of selectors) { content = await page.evaluate((sel) => { const element = document.querySelector(sel); return element ? element.innerText : null; }, selector); // 找到内容后跳出循环,避免被后续选择器覆盖 if (content) break; }
5. 验证版本兼容性
确保puppeteer-core与@sparticuz/chromium版本匹配,版本不兼容会导致浏览器通信异常,建议参考@sparticuz/chromium文档使用指定兼容版本。
6. 检查网络访问权限
- 若Lambda部署在VPC中,需配置NAT网关以允许访问公网目标URL
- 确认目标网站未屏蔽Lambda的IP段
修正后的完整代码
const puppeteer = require("puppeteer-core"); const chromium = require("@sparticuz/chromium"); exports.handler = async function (event) { const { url } = event.queryStringParameters; let browser = null; let content = null; // 正确设置无头模式 chromium.setHeadlessMode(true); try { browser = await puppeteer.launch({ executablePath: await chromium.executablePath(), headless: chromium.headless, ignoreHTTPSErrors: true, defaultViewport: chromium.defaultViewport, args: chromium.args, }); const page = await browser.newPage(); // 优化导航等待策略 await page.goto(url, { waitUntil: "networkidle2" }); const selectors = [ "article", "main", ".post", ".post-content", ".article-content", "#content", ".content", ".new-article", ".c-articleContent", ]; // 修复循环逻辑,找到内容即终止 for (let selector of selectors) { content = await page.evaluate((sel) => { const element = document.querySelector(sel); return element ? element.innerText : null; }, selector); if (content) break; } if (content) { console.log("------------- 网页内容 -------------- ", content); await page.close(); return { statusCode: 200, body: content, }; } console.error(`未在URL: ${url}中找到匹配的文章内容`); return { statusCode: 404, body: JSON.stringify({ message: "未找到文章内容" }), }; } catch (error) { console.error("--------- 错误详情 ---------", error); return { statusCode: 500, body: JSON.stringify({ error: error.message }), }; } finally { if (browser !== null) { await browser.close(); } } };
内容的提问来源于stack exchange,提问作者Manpreet Singh Bhullar
相关产品推荐
相关产品推荐

