当前位置: 首页 > news >正文

Linux设置定时作业执行node.js脚本

需求

定时作业使用puppeteer工具后台打开sapui5 web应用,截图发送到企业微信

1.timer和service文件路径/etc/systemd/system/

service代码

[Unit]
Description=1000DayPushWx Service
After=network.target[Service]
Type=oneshot
User=root
Group=root
WorkingDirectory=/opt/zauto
ExecStart=/usr/bin/node /opt/zauto/1000DayPushWx.js
StandardOutput=journal
StandardError=journal
Environment=NODE_ENV=production[Install]
WantedBy=multi-user.target

js脚本路径

timer代码

[Unit]
Description=Run 1000DayPushWx daily
Requires=1000DayPushWx.service[Timer]
# 每天上午 9:10 执行
OnCalendar=*-*-* 09:10:00
Persistent=true[Install]
WantedBy=timers.target 

2.node.js脚本代码

const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
const os = require('os');// 日志写入函数
function writeLog(message) {const logPath = path.join(__dirname, '1000_day_push.log');const time = new Date().toISOString();fs.appendFileSync(logPath, `[${time}] ${message}\n`);console.log(`[${time}] ${message}`);
}// 根据操作系统确定Chrome路径
function getChromePath() {const platform = os.platform();if (platform === 'win32') {return 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';} else if (platform === 'linux') {// Linux 系统下的 Chrome 路径const possiblePaths = ['/usr/bin/google-chrome','/usr/bin/google-chrome-stable','/usr/bin/chromium','/usr/bin/chromium-browser'];for (const chromePath of possiblePaths) {if (fs.existsSync(chromePath)) {return chromePath;}}// 如果找不到,让 Puppeteer 使用内置的 Chromiumreturn null;}return null;
}(async () => {const chromePath = getChromePath();const launchOptions = {headless: true,args: ['--window-size=800,1700','--no-sandbox','--disable-setuid-sandbox','--disable-dev-shm-usage','--disable-gpu','--no-first-run','--no-zygote','--single-process']};// 如果找到了 Chrome 路径,则使用它if (chromePath) {launchOptions.executablePath = chromePath;writeLog(`使用 Chrome 路径: ${chromePath}`);} else {writeLog('使用 Puppeteer 内置的 Chromium');}const browser = await puppeteer.launch(launchOptions);const page = await browser.newPage();await page.setViewport({ width: 800, height: 1700 });// 设置更长的超时时间await page.setDefaultTimeout(60000);// 设置 Basic Auth 账号密码await page.authenticate({username: 账号,password: 密码});writeLog('已设置Basic Auth');// 访问页面,等待网络空闲await page.goto('http://ip/zfiori_fi06/index.html', {waitUntil: 'networkidle2',timeout: 60000});writeLog('页面打开成功');// 等待 UI5 应用完全初始化writeLog('等待UI5应用初始化...');await page.waitForFunction(() => {return window.sap && window.sap.ui && window.sap.ui.getCore() && window.sap.ui.getCore().getComponent;}, { timeout: 30000 });writeLog('UI5应用初始化完成');// 等待页面元素出现,增加重试机制writeLog('查找page元素...');let pageElement = null;let retryCount = 0;const maxRetries = 3;while (!pageElement && retryCount < maxRetries) {try {pageElement = await page.waitForSelector('[id$="page"]', {timeout: 20000,visible: true});writeLog('page元素加载完成');break;} catch (error) {retryCount++;writeLog(`第 ${retryCount} 次尝试失败,等待 3 秒后重试...`);await page.waitForTimeout(3000);}}if (!pageElement) {writeLog('ERROR: 无法找到page元素,保存调试截图');await page.screenshot({ path: 'debug-page-not-found.png' });throw new Error('无法找到page元素');}// 等待页面完全渲染await new Promise(resolve => setTimeout(resolve, 5000));writeLog('页面渲染完成');// 等待 VizFrame 元素加载writeLog('等待day viz空间加载开始');const vizSelectors = ['[id$="idVizFrame5"]','[id$="idVizFrame6"]','[id$="idVizFrame7"]'];for (const selector of vizSelectors) {try {await page.waitForSelector(selector, { timeout: 30000,visible: true });writeLog(`VizFrame元素 ${selector} 加载完成`);} catch (error) {writeLog(`ERROR: VizFrame元素 ${selector} 加载失败`);// 保存调试截图await page.screenshot({ path: `debug-vizframe-${selector}.png` });throw error;}}writeLog('等待day viz空间加载完成');// 等待额外时间确保图表完全渲染await new Promise(resolve => setTimeout(resolve, 3000));writeLog('图表渲染完成');// 查找并点击截图按钮writeLog('查找截图按钮...');try {await page.waitForSelector('[id$="idjtButton"]', { timeout: 15000,visible: true });await page.click('[id$="idjtButton"]');writeLog('已点击截图按钮');} catch (error) {writeLog('ERROR: 无法找到或点击截图按钮');await page.screenshot({ path: 'debug-button-not-found.png' });throw error;}writeLog('已发送日数据');// 等待操作完成await new Promise(resolve => setTimeout(resolve, 5000));writeLog('操作完成');await browser.close();writeLog('浏览器已关闭');})().catch(error => {writeLog(`脚本执行失败: ${error.message}`);process.exit(1);
});

3.启动定时作业的linux命令

启用定时器(开机自启)

systemctl enable 1000DayPushWx.timer

启动定时器

systemctl start 1000DayPushWx.timer

检查状态

systemctl status 1000DayPushWx.timer

看到下图结果,说明启动成功

http://www.dtcms.com/a/418949.html

相关文章:

  • XXE - 实体注入(xml外部实体注入)
  • MySQL查询性能优化核心知识点总结
  • 自然语言处理(03)
  • 哈尔滨速成网站建设公司装修费用会计分录
  • 做网站亏本太原市城乡建设局网站
  • 基于本地运行的OCR在特别场景的应用
  • 网站被host重定向wordpress图像居中
  • 十大AI驱动的网络安全解决方案对比分析
  • 09.【Linux系统编程】“文件“读写操作,Linux下一切皆文件!
  • SkyVLN: 城市环境中无人机的视觉语言导航和 NMPC 控制;香港科技大学
  • 【React 状态管理深度解析:Object.is()、Hook 机制与 Vue 对比实践指南】
  • react-lottie动画组件封装
  • 哈尔滨网站建设吕新松做搜索引擎网站
  • PostgreSQL 流复制参数 - synchronous_commit
  • BPEL:企业流程自动化的幕后指挥家
  • 企业网站开发一薇设计说明英语翻译
  • 搭建 Nexus3 私服并配置第三方 Maven 仓库(阿里云等)和优先级
  • JVM 深入研究 -- 详解class 文件
  • Apache Airflow漏洞致敏感信息泄露:只读用户可获取机密数据
  • 第十六周-基本量子3
  • 手机微网站怎么制作缪斯国际设计董事长
  • 在 Spring Cloud Gateway 中实现跨域(CORS)的两种主要方式
  • SQL Server从入门到项目实践(超值版)读书笔记 27
  • 【Git】项目管理全解
  • rdm响应式网站开发企业年报网上申报流程
  • 昆山开发区网站制作网站建设文档模板
  • PySide6调用OpenAI的Whisper模型进行语音ASR转写
  • 网站怎么被黑磁力蜘蛛
  • nginx反向代理和负载均衡
  • 外贸seo外贸推广外贸网站建设外贸网站建设网站域名信息查询