Puppeteer网页监控代码崩溃排查及文本检测改造求助
问题解决与代码改造方案
一、崩溃原因分析与修复
你的代码每12秒启动一个全新的Puppeteer浏览器实例,但从未关闭浏览器进程,短时间内会堆积大量僵尸进程,耗尽系统内存导致崩溃。
修复方案:两种可选方式
方案1:每次检测后关闭浏览器(简单直接)
修改getText函数,确保无论检测成功或失败,都关闭浏览器释放资源:
const pt = require('puppeteer') const axios = require('axios') process.setMaxListeners(0); async function getText(){ let browser; try { browser = await pt.launch({ headless: 'new', // 使用新版无头模式,稳定性更强 args: ['--no-sandbox', '--disable-setuid-sandbox'] // 服务器环境必备参数 }) const page = await browser.newPage() await page.setDefaultNavigationTimeout(0); await page.goto('https://mieciusio.pl/kontakt.html') // 后续替换为文本检测逻辑,暂时保留原逻辑示例 if (await page.$("[class='p-style btn-resize-mode label-bloc-2-style label-1-style']")) { console.log("found") } else { await axios.post('https://hooks.slack.com/services/MYUniqeID', {text: 'Its changed'}) } } catch (err) { console.error('检测出错:', err) // 可选:出错时发送异常通知到Slack await axios.post('https://hooks.slack.com/services/MYUniqeID', {text: `检测失败:${err.message}`}) } finally { // 无论结果如何,关闭浏览器释放内存 if (browser) await browser.close() } } setInterval(getText, 12000)
方案2:复用浏览器实例(性能更优)
避免频繁启动关闭浏览器,只初始化一次浏览器,每次检测新建页面:
const pt = require('puppeteer') const axios = require('axios') process.setMaxListeners(0); let browser; // 初始化浏览器实例 async function initBrowser() { browser = await pt.launch({ headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox'] }) } async function getText(){ let page; try { if (!browser) await initBrowser(); page = await browser.newPage() await page.setDefaultNavigationTimeout(0); await page.goto('https://mieciusio.pl/kontakt.html') // 后续替换为文本检测逻辑,暂时保留原逻辑示例 if (await page.$("[class='p-style btn-resize-mode label-bloc-2-style label-1-style']")) { console.log("found") } else { await axios.post('https://hooks.slack.com/services/MYUniqeID', {text: 'Its changed'}) } } catch (err) { console.error('检测出错:', err) await axios.post('https://hooks.slack.com/services/MYUniqeID', {text: `检测失败:${err.message}`}) } finally { // 关闭当前页面,保留浏览器实例 if (page) await page.close() } } // 启动时初始化浏览器,再开始定时检测 initBrowser().then(() => { setInterval(getText, 12000) })
二、文本检测逻辑改造
将检测元素类的逻辑替换为检测文本,分两种常用场景:
场景1:检测整个页面是否包含指定文本
// 替换原元素检测的if语句 const pageText = await page.evaluate(() => document.body.textContent) const targetText = "你需要检测的目标文本" // 替换为实际要监控的文本内容 if (pageText.includes(targetText)) { console.log("检测到目标文本") } else { await axios.post('https://hooks.slack.com/services/MYUniqeID', {text: '页面文本已变更:未找到目标文本'}) }
场景2:检测特定元素内的文本
如果只需要监控某个特定元素里的文本,先定位元素再获取内容:
// 替换原元素检测的if语句 const elementText = await page.evaluate(() => { const element = document.querySelector("目标元素选择器") // 比如".contact-title"或"#contact-content" return element ? element.textContent.trim() : "" }) const targetText = "你需要检测的目标文本" if (elementText.includes(targetText)) { console.log("检测到目标文本") } else { await axios.post('https://hooks.slack.com/services/MYUniqeID', {text: '指定元素文本已变更:未找到目标文本'}) }
三、远程服务器部署建议
- 安装Node.js环境:选择LTS版本,保证兼容性和稳定性。
- 使用进程管理工具:用
pm2管理进程,实现崩溃自动重启:- 安装pm2:
npm install -g pm2 - 启动程序:
pm2 start your-script.js --name "web-monitor" - 查看运行日志:
pm2 logs web-monitor - 设置开机自启:
pm2 startup&&pm2 save
- 安装pm2:
- 安装系统依赖:Linux服务器需安装Puppeteer运行所需的系统库:
sudo apt-get update sudo apt-get install -y libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libgbm1 libasound2
内容的提问来源于stack exchange,提问作者Damian Z
相关产品推荐
相关产品推荐

