Node使用Selenium进行前端自动化操作的代码实现


Posted in Javascript onOctober 10, 2019

前言:

最近项目中有类似的需求:需要对前端项目中某一个用户下的产品数据进行批量的处理。手动处理的流程大概是首先登录系统,获取到当前用户下的产品列表,点击产品列表的中产品项进入详情页,对该产品进行一系列的操作,然后保存退出。因为当前有20多万条数据,手动一条一条的处理不太现实,所以希望通过写脚本的方式来进行处理。

需求分析

其实这个需求还算比较简单,需要实现的点主要有三个,一是如何进行登录,获取登录信息,查询当前用户下的产品数据;二是如何知道当前数据是否处理完,然后退出当前的处理流程;三是如何异步的处理一批数据。

所以需要做的工作就是模拟登录,调用产品列表的查询接口获取产品ID集合,然后循环遍历当前的集合,通过产品ID跳转产品详情页面,模拟页面按钮的点击操作,监听处理完成的动作,退出当前的流程。

Selenium 介绍

What is Selenium?
Selenium automates browsers. That's it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) be automated as well.
Selenium has the support of some of the largest browser vendors who have taken (or are taking) steps to make Selenium a native part of their browser. It is also the core technology in countless other browser automation tools, APIs and frameworks.

翻译过来大致意思就是: Selenium 可以自动化操作浏览器。怎么去使用Selenium 的功能完全取决于我们自己。它主要还是使用在web应用的自动化测试上。但是他的功能并不仅限于此。那些枯燥的基于web的管理任务也可以自动化。很多流行的浏览器都采取了一些措施来支持Selenium实现本地化。它也是很多浏览器自动化工具、API自动化以及框架的核心技术。

Selenium 主要分 Selenium WebDriver 以及 Selenium IDE。我主要结合Node来介绍 Selenium WebDriver 的安装使用。本文主要介绍Selenium 结合 Node 的安装使用。需要进行深入研究的同学请自行查看官网文档。

Node 环境搭建

1. node的安装在此不再赘述。点击链接查看官网下载安装方法。
2. express安装

$ npx express-generator

或者

$ npm install -g express-generator

创建项目:

$ express --view=ejs selenium-start
$ cd selenium-start
$ yarn

启动项目:

$ DEBUG=myapp:* yarn start

至此,Node 项目创建完毕。接下来我们就可以在项目中集成Selenium WebDriver

Selenium WebDriver 集成

1. 安装selenium-webdriver

yarn add selenium-webdriver

2. 下载安装支持不同浏览器的驱动。(此处只介绍Chrome驱动)

[ChromeDriver][3]
下载并解压文件,同时把解压的执行文件放置到 /usr/bin目录下。或者设置相应的PATH路径,确保可执行文件在PATH路径中。

开始使用

进入我们刚才创建的项目文件夹,目录如下:

Node使用Selenium进行前端自动化操作的代码实现

页面添加一个开始按钮,以及给按钮添加事件。

找到 views/index.ejs, 添加如下代码:(为了方便操作,引入了jquery, axios, 所以需要下载准备好)

Node使用Selenium进行前端自动化操作的代码实现

Node使用Selenium进行前端自动化操作的代码实现

添加对应的路由

Node使用Selenium进行前端自动化操作的代码实现

在app.js文件中,引入路由chromeDriver

var chromeDriverRouter = require('./routes/chromeDriver');
 app.use('/chromeDriver', chromeDriverRouter);

引入selenium-webdriver

在routes/chromeDirver.js文件中,我们添加了一个方法handleBaiDuDriver,这个方法用于处理模拟百度搜索自动化的一些测试。

首先我们需要在文件顶部引入selenium-webdriver

const {Builder, By, Key, until} = require('selenium-webdriver');

 // Builder: 用于创建一个WebDriver实例。
 // By: 表示通过什么方式来查找页面的元素。
   // By.className( name ) → By
   // By.css( selector ) → By
   // By.id( id ) → By
   // By.js( script, ...var_args ) → function(WebDriver): Promise
   // By.linkText( text ) → By
   // By.name( name ) → By
   // By.partialLinkText( text ) → By
 // Key: 表示键盘上一系列的按键。
 // until: 定义了一些工具类的方法。

然后书写我们的方法体里的内容。

const handleBaiDuDriver = async () => {
   let driver = await new Builder().forBrowser('chrome').build();
   try {
     await driver.get('http://www.baidu.com');
 
     await driver.findElement(By.id('kw')).sendKeys('webdriver', Key.RETURN);//正常使用
 
     await driver.findElement(By.id('su')).click();
 
     await driver.wait(until.titleIs('百度一下,你就知道'), 1000);
     
   } catch (error) {
     console.log(error)
   } finally {
     await driver.sleep(2000);
     await driver.quit();
   }
 }

启动服务,查看效果。

启动服务之后,我梦能看到如下的界面。

Node使用Selenium进行前端自动化操作的代码实现

点击页面中的【点击开始】按钮,最终能够看到如下的界面,为了演示我做了两秒的延迟。生成的gif图有9M多,无法上传。后续可以下载源码运行看效果。

Node使用Selenium进行前端自动化操作的代码实现

获取登录信息

以上是selenium-webdriver的简单集成。在之前我们提到过实际需求中如何获取登录信息的问题。在访问产品列表页面的时候需要进行登录校验。如果没有登录则会跳转界面。由于我们的登录页是通过iframe来嵌套引入的。由于暂时还没有了解如何处理iframe里的操作,所以没法去模拟用户名密码的输入。

查看API文档,WebDriver 会有一个manage方法:

this.manage() → Options

该方法会返回一个Options实例,具有如下的方法:

Node使用Selenium进行前端自动化操作的代码实现

其中有对cookie的操作方法。所以可以通过首次输入用户信息并进行缓存的方式来实现登录态的保存。在下一次再打开页面的时候直接从缓存里获取cookie信息,并通过addCookie方法进行cookie的设置。但是由于我不知道什么时候、多长时间登录才会成功,所以在获取cookie的时候需要通过不断循环的方式去获取,直到拿到cookie。当然可以设置一个超时时间。超时之后就退出当前driver。

// 缓存cookie
 async function setCookies(driver) {
   const manage = driver.manage();
   let sleepTime = 6000;
   await driver.sleep(sleepTime);
   let cookies = null
   try {
     cookies = await manage.getCookies();  
   } catch (error) {
   }
   while (!cookies || !findSessionIdFromCookies(cookies)) {
     await driver.sleep(2000)
     sleepTime += 2000;
     try {
       cookies = await manage.getCookies();
     } catch (error) {
     }
   }
   if (cookies && findSessionIdFromCookies(cookies)) {
     cache.cookies = cookies; // cache是全局用于缓存cookie的对象
     cache.cookiesStr = cache.cookies.map((cookie) => {
       return `${cookie.name}=${cookie.value}`
     }).join(';');
   }
   return cookies;
 }
 
 
 // 设置cookie
 async function initCookies(driver) {
   const cookies = cache.cookies;
   if (cookies && cookies.length > 0) {
     await driver.manage().deleteAllCookies();
     for (let i = 0 ; i < cookies.length; i++) {
       cookie = cookies[i];
       await driver.manage().addCookie(cookie);    
     };
   }
 }

获取到cookie 信息之后就可以请求产品列表以及通过产品ID进入产品详情页。然后再模拟页面按钮点击操作即可。

Github地址

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
document.all的一个比较完整的总结及案例
Jan 31 Javascript
Javascript+CSS实现影像卷帘效果思路及代码
Oct 20 Javascript
JS实现淡蓝色简洁竖向Tab点击切换效果
Oct 06 Javascript
JS实现的页面自定义滚动条效果
Oct 26 Javascript
值得分享的bootstrap table实例
Sep 22 Javascript
jQuery居中元素scrollleft计算方法示例
Jan 16 Javascript
ReactNative踩坑之配置调试端口的解决方法
Jul 28 Javascript
node结合swig渲染摸板的方法
Apr 11 Javascript
微信小程序scroll-view实现滚动穿透和阻止滚动的方法
Aug 20 Javascript
vue利用v-for嵌套输出多层对象,分别输出到个表的方法
Sep 07 Javascript
微信小程序 wepy框架与iview-weapp的用法详解
Apr 10 Javascript
基于JS实现简单滑块拼图游戏
Oct 12 Javascript
Vue 开发必须知道的36个技巧(小结)
Oct 09 #Javascript
浅谈vue项目用到的mock数据接口的两种方式
Oct 09 #Javascript
Vue3.0数据响应式原理详解
Oct 09 #Javascript
Vue分页插件的前后端配置与使用
Oct 09 #Javascript
vue3修改link标签默认icon无效问题详解
Oct 09 #Javascript
将RGB值转换为灰度值的简单算法
Oct 09 #Javascript
基于Vue 撸一个指令实现拖拽功能
Oct 09 #Javascript
You might like
php中并发读写文件冲突的解决方案
2013/10/25 PHP
PHP远程连接oracle数据库操作实现方法图文详解
2019/04/11 PHP
JavaScript 异步调用框架 (Part 6 - 实例 &amp; 模式)
2009/08/04 Javascript
js原生态函数中使用jQuery中的 $(this)无效的解决方法
2011/05/25 Javascript
Javascript 修改String 对象 增加去除空格功能(示例代码)
2013/11/30 Javascript
javascript创建数组之联合数组的使用方法示例
2013/12/26 Javascript
完美解决IE不支持Data.parse()的问题
2016/11/24 Javascript
详解JavaScript时间处理之几个月前或几个月后的指定日期
2016/12/21 Javascript
vue移动端裁剪图片结合插件Cropper的使用实例代码
2017/07/10 Javascript
JavaScript门面模式详解
2017/10/19 Javascript
JavaScript自执行函数和jQuery扩展方法详解
2017/10/27 jQuery
JS实现调用本地摄像头功能示例
2018/05/18 Javascript
详解angular部署到iis出现404解决方案
2018/08/14 Javascript
vue 项目接口管理的实现
2019/01/17 Javascript
Javascript的this详解
2019/03/23 Javascript
JavaScript实现背景自动切换小案例
2019/09/27 Javascript
[01:05]DOTA2完美大师赛趣味视频之选手教你打职业
2017/11/23 DOTA
python通过加号运算符操作列表的方法
2015/07/28 Python
Python中使用插入排序算法的简单分析与代码示例
2016/05/04 Python
老生常谈Python进阶之装饰器
2017/05/11 Python
使用Numpy读取CSV文件,并进行行列删除的操作方法
2018/07/04 Python
Python3自动签到 定时任务 判断节假日的实例
2018/11/13 Python
python 堆和优先队列的使用详解
2019/03/05 Python
Django打印出在数据库中执行的语句问题
2019/07/25 Python
Python爬虫爬取煎蛋网图片代码实例
2019/12/16 Python
Python使用正则表达式实现爬虫数据抽取
2020/08/17 Python
美国农场商店:Blain’s Farm & Fleet
2020/01/17 全球购物
领导干部考察材料
2014/02/08 职场文书
2014年会计工作总结
2014/11/27 职场文书
工程项目经理岗位职责
2015/02/02 职场文书
幼儿园园长个人总结
2015/03/02 职场文书
成事在人观后感
2015/06/16 职场文书
2019毕业典礼主持词!
2019/07/05 职场文书
解析:创业计划书和商业计划书二者之间到底有什么区别
2019/08/14 职场文书
MySQL系列之十二 备份与恢复
2021/07/02 MySQL
Nginx部署vue项目和配置代理的问题解析
2021/08/04 Servers