selenium-webdriver 阿里云ARMS 自动化巡检

    很久没更新了,今天分享一篇关于做项目巡检的内容,这部分,前两天刚在公司做了部门分享,趁着劲还没过,发出来跟大家分享下。

一、本地巡检实现

1. Selenium Webdriver(SW) 简介

Selenium Webdriver(以下简称SW) 是一个用于自动化 web 浏览器操作的工具。

它提供了一组用于模拟用户在网页中的交互的 API,可以通过编程方式来控制浏览器并执行各种操作,例如点击、填写表单、提取数据等。

SW 支持多种编程语言,包括 Java、Python、JavaScript(Node.js)等,本次分享我们主要关注 SW 的 JavaScript 版本。

2. SW 能做什么

  • 自动化测试:Selenium Webdriver 可以通过编写代码来模拟用户在浏览器中的行为,例如点击链接、填写表单、提交数据、执行搜索等。它提供了对多种浏览器的支持,包括 Chrome、Firefox、Safari、Edge、Internet Explorer 等,可以用于编写和执行自动化测试用例,验证 Web 应用程序的功能和性能。

  • 浏览器自动化:Selenium Webdriver 可以以编程方式控制浏览器的行为和属性,例如打开指定的网址、最大化窗口、切换标签页、处理弹窗、截图等。它能够模拟真实用户在浏览器中的操作,并提供对 DOM 元素的定位和操作的方法。

  • 数据抓取:Selenium Webdriver 可以被用于抓取网页上的数据。通过模拟用户的交互操作,可以实现从网页上提取信息、进行表单填充和提交、模拟点击和滚动等操作,以便自动化地获取需要的数据。

  • 跨浏览器测试:Selenium Webdriver 提供了一致的 API,可以编写一套测试脚本并在不同的浏览器上运行,以验证 Web 应用程序在各个浏览器上的兼容性和一致性。

3. SW 巡检

这个是当前ARMS上最主要的监控指标,我们每天巡检要做的事,就是对这些数据做采集;同时对比过往指标,做异常分析、性能监控、用户行为分析等相关工作

3.1 浏览器相关

3.1.1 浏览器驱动

浏览器

驱动

chrome

chromedriver.exe

Firefox

 geckodriver.exe

IE

 IEDriverServer.exe

3.1.2 浏览器相关配置
const { Options } = require('selenium-webdriver/chrome')let options = new Options() 
options.addArguments('--headless')
options.addArguments('--no-sandbox')
options.addArguments('--disable-gpu-sandbox')
options.addArguments('--disable-dev-shm-usage')
options.addArguments('--disable-extensions')
options.addArguments('--remote-debugging-port=9222')   
options.addArguments('--window-size=1920,1080'); options.addArguments('--start-fullscreen')    
options.addArguments('disable-blink-features=AutomationControlled') 

说明

参数

描述

--headless

无界面模式,Linux 上运行时由于缺少图形界面,可以避免显示窗口相关问题

--no-sandbox 

 禁用 Chrome 浏览器的沙盒模式,避免在无界面模式下的一些权限问题

--disable-gpu-sandbox

禁用 Chrome 浏览器的 GPU 沙盒,也是为了避免在无界面模式下出现问题

--disable-dev-shm-usage

 禁用 Chrome 浏览器的 /dev/shm 临时文件系统的使用

--disable-extensions

禁用 Chrome 浏览器的扩展插件功能,提高运行效率

--remote-debugging-port=9222

启用 Chrome 浏览器的远程调试端口,允许远程调试协议与浏览器进行交互

--window-size=1920,1080

 设置浏览器窗口大小

--start-fullscreen

 全屏模式

disable-blink-features=AutomationControlled

禁用 AutomationControlled特性,以避免被浏览器检测到自动化程序的控制。

3.2 巡检流程

巡检基本流程

1)登录                     输入账号、密码、滑动验证

2)获取数据             读取DOM文本、模拟接口获取数据

3)生成表格并发送  将数据转化成带样式的表格,通过企微机器人发送到微信群

3.2.1 登录
// 跳转登录页
await driver.get('https://signin.aliyun.com/login.htm?callback=https%3A%2F%2Farms.console.aliyun.com%2Fretcode#/main')
driver.manage() // 等待页面加载完成
await driver.wait(async function () {let readyState = await driver.executeScript('return document.readyState')console.info('\x1B[37m ♫ Login  readyState=' + readyState)return readyState === 'complete'
}, 3000)
await sleep(1000)// 输入用户名
let inputEl = await driver.findElement(By.xpath('//input[@name="username"]'))
await inputEl.clear();
await sleep(100)
await inputEl.sendKeys(USERNAME)
await sleep(100)
await (await driver.findElement(By.css('.next-col > button.next-btn-primary'))).click();// 等待
await sleep(2000)
await driver.wait(async function () {let readyState = await driver.executeScript('return document.readyState')return readyState === 'complete'
}, 5000)// 输入密码
let pwdInputEl = await driver.findElement(By.xpath('//input[@name="password"]'))    
await pwdInputEl.clear();
await sleep(100)
await pwdInputEl.sendKeys(PASSWORD)
await sleep(3000)// 点击登录
await (await driver.findElement(By.css('.next-col > button.next-btn-primary'))).click();
await sleep(5000)
url = await driver.getCurrentUrl()// 滑块验证
if(url.indexOf('https://signin.aliyun.com/login.htm') === 0){slideVerify(driver,'#baxia-dialog-content','.sm-pop-inner .btn_slide');await sleep(5000)
}

3.2.2 获取数据
1)读取DOM文本
async function getPvData(driver, times = 0) {const resultMap = {}try {let pvSpan = await driver.findElement(By.css('div[data-e2e-id="summary-title-pv"] span.noclick-title'))let uvSpan = await driver.findElement(By.css('div[data-e2e-id="summary-title-uv"] span.noclick-title'))let jsErrorRate = await driver.findElement(By.css('span[data-e2e-id="card-content_title-jsErrorRate"]'))let apiSucRate = await driver.findElement(By.css('span[data-e2e-id="card-content_title-api"]'))let jsError = await driver.findElement(By.css('span[data-e2e-id="card-content_title-jsError'))let apiError = await driver.findElement(By.css('span[data-e2e-id="card-content_title-apiError"]'))let resourceError = await driver.findElement(By.css('span[data-e2e-id="card-content_title-resourceError"]'))const pvData = await pvSpan.getText()const jsErrorRateData = await jsErrorRate.getText()const apiSucRateData = await apiSucRate.getText()const jsErrorData = await jsError.getText()const apiErrorData = await apiError.getText()const uvData = await uvSpan.getText()const resourceErrorData = await resourceError.getText()if (!pvData || pvData.indexOf('--') > -1 || !jsErrorRateData || jsErrorRateData.indexOf('--') > -1 || !apiSucRateData || apiSucRateData.indexOf('--') > -1|| !jsErrorData || jsErrorData.indexOf('--') > -1  || !uvData || uvData.indexOf('--') > -1) {if (times > 8) {return null}await sleep(3000)return await getPvData(driver, ++times)} else {resultMap.pv = pvDataresultMap.jsErrorRate = jsErrorRateDataresultMap.apiSucRate = apiSucRateDataresultMap.jsError = jsErrorDataresultMap.apiError = apiErrorDataresultMap.uv = uvData resultMap.resourceError = resourceErrorDatareturn resultMap}} catch (e) {if (times > 8) {return null}await sleep(3000)return await getPvData(driver, ++times)}
}

元素定位方法


driver.findElement(By.css('.btn_slide'))driver.findElement(By.id("login_button"))driver.findElements(By.className('con_list_item'))driver.findElement(By.xpath('//input[@name="fm-login-id"]'))driver.executeScript('document.querySelector(\'.sts-loginout-wrap\').click()') 

2)模拟发起请求
function requestWhiteScreen(driver, cookie, startDate, endDate, appId, page) {const intervalMillis = 2147483647,token = getQueryStr('XSRF-TOKEN', cookie.replace(/;/g, '&'))return driver.executeScript(`return window.fetch('https://arms.console.aliyun.com/api/retcode.json?action=RetcodeAction&eventSubmitDoGetDatas=1', { method: 'post', credentials: 'include',headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8','cookie': '${cookie}','X-XSRF-TOKEN': '${token}'},body: 'queryParams=%7B%22metric%22%3A%22webstat.sum%22%2C%22measures%22%3A%5B%22sum_val%22%5D%2C%22filters%22%3A%7B%22appId%22%3A${appId}%7D%2C%22dimensions%22%3A%5B%22key%22%5D%2C%22intervalMillis%22%3A${intervalMillis}%2C%22startTime%22%3A${startDate}%2C%22endTime%22%3A${endDate}%2C%22orderBy%22%3A%22sum_val%22%2C%22order%22%3A%22DESC%22%2C%22limit%22%3A%221000%22%7D'}).then(response => response.json())`)
}

3.2.3 生成巡检表格

为了实现表格的良好视觉效果,采用了两个主要组件,分别是 xlsx 和 xlsx-style。

xlsx                 数据整合成Excel表格

xlsx-style        渲染表格样式

xlsx 组件用于将数据整合成Excel表格的格式,而 xlsx-style 组件则提供了一系列丰富的表格样式,可以帮助我们实现带有样式的表格,从而提高表格的可读性和可视化效果。

效果

二、Linux 服务端部署

1. 代码部署

登录堡垒机

1)同步代码:进入存放项目的目录,上传项目压缩文件,通过指令解压:unzip xx.zip

2)安装依赖:npm i

3)测试巡检:npm run xx

2. 添加定时任务

2.1 创建执行文件

项目目录下,创建Shell脚本执行文件,如:h5-linux.sh

说明

  1. killall -9 xx   结束其他关联进程

  2. npm run xx        执行巡检指令

2.2 添加定时任务 

1)查看当前的定时任务:终端窗口输入 crontab -l 指令

crontab相关可参考:crontab使用方法

2)添加定时任务:终端窗口输入 crontab -e 指令,进入编辑界面,添加定时任务(*最后一个用于测试)

格式:

*     *    *   *   *  command       分   时   日   月  周   命令

说明

示例    30 8 1,15,25 * * command   每月1、15、25日的 8 : 30 执行一次

语法

 描述

*

代表所有可能的值,从左到右:分钟、小时、日期、月、星期几;

其中分钟以 0-59、小时以1~23 (0表示0点) 、日期以 1-31 、月份以 1-12 、星期几以 0-6 的数字表示(0 表示星期日,1 表示星期一,以此类推)。 如每小时的第15分钟执行一次:      15 * * * * command

,

可以用逗号隔开的值指定一个列表范围,例如:1,2,5,7,8,

-

可以用整数之间的中杠表示一个整数范围,例如 2-6 表示:2,3,4,5,6

/

用于指定时间区间,如:* 18-8/1 * * * command  晚上18点到早上8点之间,每隔一小时执行一次

2.2 测试定时任务

执行:./文件名.sh  或 sh 文件名.sh 运行任务

3. 配置日志

配置日志,用于记录巡检流程,确定问题的来源,并进行相关的故障排查。

方法:进入编辑界面,在对应任务后面新增日志

说明

语法

描述

 >> 目录/文件名.log

 日志输出目录/文件

2>&1  

是一种将标准错误输出(stderr)重定向到标准输出(stdout)的方法;确保即使发生错误,也能完整记录脚本的输出和错误信息。

三、企微机器人

1. 创建机器人

企微群 (右上角) > ... > 添加群机器人 > 新创建一个机器人 > 输入机器人名称 > 添加机器人 

2. 发送消息

获取key:点击群机器人,从Webhook 地址获取到key

2.1 发送文档

1)文件上传:

配置 formData,通过文件上传接口,将文档上传到文件系统,获取到 media_id(文件标识名)

2)发送文件到企微群:

通过配置消息类型文件标识名,使用发送接口,将文件发送到企微群中,并@对应负责人对异常指标进行分析

const key = 'xx'  
async function sendWx(filePath) {       const readStream = fs.createReadStream(filePath)const formData = new FormData()formData.append('media', readStream)   const mediaId = await axios.post(`https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key=${key}&type=file`, formData)  axios({ url:`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${key}`,method: 'post', headers: {'Content-Type': 'application/json',},data: {msgtype: 'file',file: {'media_id': mediaId?.data?.media_id||''}}  }).then(() =>{ fs.unlinkSync(filePath) console.info('\x1B[37m✔ 巡检已发送企微群\x1B[32m')  const { mobile } = dutyArrangement()    if(mobile){ sentWxMsg('请项目负责人填写指标分析',mobile)}})    
}

2.2 发送消息

消息支持多种类型的配置,用户可以根据自身需求,选择不同的消息类型

msgtype 支持类型

  • text                        文本消息
  • file                        文件消息
  • markdown                 Markdown 格式的消息
  • image                      图片消息
  • news                       新闻消息
  • template_card        模板卡片消息
async function sentWxMsg(content,mentioned_mobile_list=[]){axios({ url:`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${key}`,method: 'post', headers: {'Content-Type': 'application/json',},data: {msgtype: 'text',       text: {content,       mentioned_mobile_list,}    } }).then(() =>{ console.info('\x1B[37m✔ 巡检提示已发送企微群\x1B[32m')  })  
}

说明

参数

说明

msgtype

  消息类型

content

消息内容

mentioned_mobile_list

手机号列表,提醒手机号对应的群成员(@某个成员),@all表示提醒所有人

 Markdown 格式的消息

async function sentWxMarkdownMsg(content,tip){axios({ url:`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${key}`,method: 'post', headers: {'Content-Type': 'application/json',},data: {msgtype: 'markdown',       markdown: {content            }} }).then(() =>{ console.info(`\x1B[37m✔ ${tip}\x1B[32m`)  })  
}const markdown = '昨天:ARMS--JS错误数:<font color="warning">8,686</font>,上周平均值为:<font color="info">2025.29</font>'
sentWxMarkdownMsg(markdown,'错误提示')

 *注意:markdown消息不支持@成员

效果

图文消息

async function sentWxNewsMsg(news={},tip){axios({ url:`https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${key}`,method: 'post', headers: {'Content-Type': 'application/json',},data: {msgtype: 'news',       news      } }).then(() =>{ console.info(`\x1B[37m✔ ${tip}\x1B[32m`)  })  
}const news = {articles : [{title : '🌕月满情浓,好耶相送',description : '花好月圆人团圆,迎风赏月合家欢',url : 'https://www.baidu.com/',picurl:'https://i.hd-r.cn/317e50d14adb76e4e322df93a1da07b1.png'                }]
}
sentWxNewsMsg(news,'图文消息已发送')

效果

最后,佳节将至,祝大家:

花好月圆人团圆,迎风赏月合家欢 ♥

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/88299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

多线程的死锁问题

可重入和不可重入&#x1f60a;&#x1f60a;&#x1f60a; 一个线程针对同一个对象,连续加锁两次,是否会有问题 ~~ 如果没问题,就叫可重入的.如果有问题,就叫不可重入的. 代码示例&#x1f349;&#x1f349;&#x1f349;: synchronized public void add(){synchronized (…

vue wangEditor富文本编辑器 默认显示与自定义工具栏配置

1.vue 显示wangEditor富文本编辑器 <template><div style"border: 1px solid #ccc;"><Toolbar style"border-bottom: 1px solid #ccc" :editor"editor" :defaultConfig"toolbarConfig" :mode"mode"/><…

在线商城项目EShop【ListView、adapter】

要求如下&#xff1a; 1、创建在线商城项目EShop&#xff1b; 2、修改布局文件activity_main.xml&#xff0c;使用LineaLayout和ListView创建商品列表UI&#xff1b; 3、创建列表项布局list_item.xml&#xff0c;设计UI用于显示商品图标、名称和价格信息&#xff1b; 4、创…

流媒体播放器EasyPlayer.js无法播放H.265的情况是什么原因?该如何解决?

H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器&#xff0c;可支持多种流媒体协议播放&#xff0c;可支持H.264与H.265编码格式&#xff0c;性能稳定、播放流畅&#xff0c;能支持WebSocket-FLV、HTTP-FLV&#xff0c;HLS&#xff08;m3u8&#…

外卖小程序开发指南:打造完美的点餐体验

第一步&#xff1a;项目设置和初始化 首先&#xff0c;您需要选择一个适合您的开发平台&#xff0c;例如微信小程序、支付宝小程序或其他移动应用平台。接下来&#xff0c;创建一个新的小程序项目&#xff0c;并初始化所需的文件和目录。 示例代码&#xff08;微信小程序&am…

自定义类型:结构体,枚举,联合

自定义类型&#xff1a;结构体&#xff0c;枚举&#xff0c;联合 前言&#xff1a;结构体1.结构体类型的声明2.结构的自引用3.结构体变量的定义和初始化4.结构体内存对齐5.结构体传参6.结构体实现位段&#xff08;位段的填充&可移植性&#xff09; 枚举1.枚举类型的定义2.枚…

多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测(SE注意力机制)

多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测&#xff08;SE注意力机制&#xff09; 目录 多维时序 | MATLAB实现WOA-CNN-BiGRU-Attention多变量时间序列预测&#xff08;SE注意力机制&#xff09;预测效果基本描述模型描述程序设计参考资料 预测效果 基本…

企业架构相关

数据架构的作用首先是找到所有的业务对象 和数据对象。 在数据对象分析里面有一个重点就是主数据识别和分析。

Python接口自动化搭建过程,含request请求封装

接口测试自动化好处 显而易见的好处就是解放双手&#x1f600;。 可以在短时间内自动执行大量的测试用例通过参数化和数据驱动的方式进行测试数据的变化&#xff0c;提高测试覆盖范围快速反馈测试执行结果和报告支持持续集成和持续交付的流程 使用Requestspytestallure搭建测…

【蓝桥杯选拔赛真题64】Scratch神奇画笔 少儿编程scratch图形化编程 蓝桥杯选拔赛真题解析

scratch神奇画笔 第十四届青少年蓝桥杯scratch编程选拔赛Stema比赛真题 一、题目要求 编程实现 1). 运行程序,背景如图所示; 2). 等待1秒后切换到下一个角色、背景(画板中简笔画为参照绘制样例); 3). 按下鼠标左键,画笔隐藏并跟随鼠标移动同时在空白处画线(松开鼠标…

除了 MySQL,这些数据库你都认识么?

什么是数据库&#xff1f; 这个问题相信对学编程的朋友们来说过于简单了&#xff0c;大家想必都是增删改查的好手。 但如果让你说出 10 种不同类型的数据库&#xff0c;阁下该如何应对&#xff1f; 这篇文章&#xff0c;是对数据库技术的一个小科普&#xff0c;希望能帮大家…

通俗易懂了解大语言模型LLM发展历程

1.大语言模型研究路程 NLP的发展阶段大致可以分为以下几个阶段&#xff1a; 词向量词嵌入embedding句向量和全文向量理解上下文超大模型与模型统一 1.1词向量 将自然语言的词使用向量表示&#xff0c;一般构造词语字典&#xff0c;然后使用one-hot表示。   例如2个单词&…

STL算术生成和集合算法

目录 算术生成算法accumulate 算术生成算法file 常用集合算法 常用集合算法 常用集合算法set_difference 算术生成算法accumulate 算术生成算法属于小型算法&#xff0c;使用时包含的头文件为 include <numeric> accumulate(iterator beg, iterator end, value); …

初识java

目录 1. cmd(命令提示符) 1. 什么是cmd 2. cmd常用命令 1. 打开cmd 2.常用命令 2. 什么是java 1. 为什么学Java? 2. JDK的下载和安装 3.第一个java程序(重点) 1.使用记事本编写程序 2.翻译文件(编译) 3.运行文件 4.配置环境变量 1.为什么要配置环境变量 2.配置…

MySQL学习笔记1

任务背景&#xff1a; 将原来的数据库从原来的MySQL-5.5 升级到现在的MySQL-5.7&#xff0c;并保证数据完整。 1&#xff09;不同版本MySQL的安装&#xff1b;yum glibc、源码安装&#xff0c;是企业100%要用到的。 2&#xff09;MySQL数据库版本升级&#xff1b;&#xff08…

AndroidStudio无法查看Compose重组次数?

印象中是一开始使用AndroidStudio LayoutInspector想查看Compose重组次数的时候&#xff0c;一开始折腾了下后来忘了这茬事了&#xff0c;最近&#x1fa9c;到期了&#xff0c;家里又换了台新的mac mini又看到这个问题&#x1f60a;&#xff0c;就想着给大家整理了一下解决方法…

互联网医院牌照|互联网医院牌照审批流程和材料

随着科技的不断进步和社会的发展&#xff0c;互联网医院已经成为了当前的热点。而互联网医院的准入门槛自然也就越来越高。如果您计划成立一个互联网医院&#xff0c;您需要了解申请互联网医院牌照所需要注意的方面以及申请的流程。 一、资质申请前的准备 1、立项阶段准备 在立…

项目开发过程中,成员提离职,怎么办?

之前写过一篇《如何应对核心员工提离职》反响特别好&#xff0c;今天做个延展篇&#xff0c;在项目过程中&#xff0c;员工突然提离职&#xff0c;我们有什么办法让项目按时按质的上线。 项目做多了&#xff0c;总会碰到这种情况。这里给大家介绍一个解决项目问题的分析方法&a…

一文教你学会ArcGIS Pro地图设计与制图系列全流程(2)

ArcGIS Pro做的成果图及系列文章目录&#xff1a; 系列文章全集&#xff1a; 《一文教你学会ArcGIS Pro地图设计与制图系列全流程&#xff08;1&#xff09;》《一文教你学会ArcGIS Pro地图设计与制图系列全流程&#xff08;2&#xff09;》《一文教你学会ArcGIS Pro地图设计与…

Apache Doris 行列转换可以这样玩

行列转换在做报表分析时还是经常会遇到的&#xff0c;今天就说一下如何实现行列转换吧。 行列转换就是如下图所示两种展示形式的互相转换 1. 行转列 我们来看一个简单的例子&#xff0c;我们要把下面这个表的数据&#xff0c;转换成图二的样式 image-20230914151818953.png …