【PUPPETEER】初探之拖拽操作(五)
一、知识点
- page.mouse
- elementHandle.boundingBox()
- ignoreDefaultArgs:['--enable-automation']
- waitUntil
二、解析知识点
1.page.mouse
以下,截图来自github puppeteer api(自行对照github) ,puppeteer已经提供给我们使用方法,很简单,move - 移动,down - 按下, up - 抬起 ,通过这个我们可以很简单的明白,场景拖拽的时候,我们先按下(down),再移动(move),最后松开(up),是不是很好理解

2.elementHandle.boundingBox()
boundingBox() 又是用来干嘛呢,我们看api, 他返回的是 x,y 坐标,还有宽度,长度,那就很好理解了,比如我上面运用了page.mouse,进行拖拽,但是我拖拽什么呢,拖拽的东西,鼠标点击后肯定有x,y坐标,也有固定的长度,不可能一直让你无限拖拽。

3.ignoreDefaultArgs:['--enable-automation']
这个是干嘛的,当我们运行发现chrome 左上角有个 Chrome 正受自动软件控制,但是有时候有的网站会检测到自动化脚本,会禁止掉,这时候我们如何避免puppeteer 被前端JS检测到
const brower = await puppeteer.launch({
executablePath:'D:\\wangxiao\\chrome-win\\chrome-win\\chrome.exe',
headless:false,
ignoreDefaultArgs:['--enable-automation']
});

三、实例
1. 登入大麦网,我们今天来注册一下,但是发现他需要滑动验证,那么我们来试一下

2. 如何定位,如何切换iframe 这边省略,前面已经讲过了,这边直接进入正题,前面代码
/**1.切换iframe,2.向输入框中输入密码**/
const brower = await puppeteer.launch({
executablePath:'D:\\wangxiao\\chrome-win\\chrome-win\\chrome.exe',
headless:false
});
const page = await brower.newPage();
await page.goto('https://passport.damai.cn/register',{waitUntil:'networkidle2'});
const frame = await page.frames().find(f => f.url().includes('https://ipassport.damai.cn/member')); await frame.waitFor('.next-input.next-large input[placeholder="输入密码"]');
await frame.type('.next-input.next-large input[placeholder="输入密码"]','122222');
3. 定位到滑动块 const element = '.nc_iconfont.btn_slide' ; 调用boundingBox(),
问:为什么要调用boundingBox()
答:为了获取滑动块的x,y 坐标
const start = await frame.waitForSelector('.nc_iconfont.btn_slide');
const startinfo = await start.boundingBox();

4.定位整个拖动的块,如何定位(省略,自己多联系) const element = '.nc-lang-cnt‘
const end = await frame.waitForSelector('.nc-lang-cnt');
const endinfo = await end.boundingBox();

5. 分析下面该怎么做,首先我们获取了start 滑动块x,y坐标后,怎么滑动呢,毫无疑问肯定调用page.mouse 方法啊,所以下面代码应该这么写
1.确定要移动的目标x,y轴
2.按下
await page.mouse.move(startinfo.x,endinfo.y);
await page.mouse.down();
6. 有了以上的操作,按下后,我们怎么移动呢,我们分析一下滑动长度是不是不能大于滑动块的宽度? 那么我们是不是得到了最大的长度 endinfo.width (前面介绍了,实在不知道调用啥的自己看api文档)
然后我们在分析,有了最大跨度,移动的时候是不是只有x轴移动,y轴没有移动呢,那么就很好做了,代码如下,代码应该很好理解,就是x 轴不能超过滑动块的宽度,并且x轴是递增的y轴是不动的,这个很好理解
for(var i=0;i<endinfo.width;i++) {
await page.mouse.move(startinfo.x+i,endinfo.y);
}
7.完整的代码
const puppeteer = require('puppeteer');
(async () => {
const brower = await puppeteer.launch({
executablePath:'D:\\wangxiao\\chrome-win\\chrome-win\\chrome.exe',
headless:false
});
const page = await brower.newPage();
await page.goto('https://passport.damai.cn/register',{waitUntil:'networkidle2'});
const frame = await page.frames().find(f => f.url().includes('https://ipassport.damai.cn/member'));
const start = await frame.waitForSelector('.nc_iconfont.btn_slide');
const startinfo = await start.boundingBox();
const end = await frame.waitForSelector('.nc-lang-cnt');
const endinfo = await end.boundingBox();
await page.mouse.move(startinfo.x,endinfo.y);
await page.mouse.down();
for(var i=0;i<endinfo.width;i++) {
await page.mouse.move(startinfo.x+i,endinfo.y);
}
await page.mouse.up();
//await brower.close();
})().catch(error =>{console.log('error')});

8.结果如图,滑动了,但是最后出错了,为什么呢 ,分析原因之一,网站检测出,我们用自动化脚本跑了,如何避免被前端JS检测到呢,用到上面讲的知识ignoreDefaultArgs:['--enable-automation']
完整代码:我们加上ignoreDefaultArgs:["--enable-automation"] 这个属性的时候发现,还是报错,那么我们在分析一下,为什么?一般自动化跑的速度要比人快的多,那么最后一步松开是不是太快导致的呢,那我们就等待1-2秒,再松开,也有可能是滑动太慢了,总之能简单处理先简单处理,以后再深入
const puppeteer = require('puppeteer');
(async () => {
const brower = await puppeteer.launch({
executablePath:'D:\\wangxiao\\chrome-win\\chrome-win\\chrome.exe',
headless:false,
ignoreDefaultArgs:["--enable-automation"]
});
const page = await brower.newPage();
await page.goto('https://passport.damai.cn/register',{waitUntil:'networkidle2'});
const frame = await page.frames().find(f => f.url().includes('https://ipassport.damai.cn/member'));
await frame.waitFor('.next-input.next-large input[placeholder="输入密码"]');
await frame.type('.next-input.next-large input[placeholder="输入密码"]','122222');
const start = await frame.waitForSelector('.nc_iconfont.btn_slide');
const startinfo = await start.boundingBox();
const end = await frame.waitForSelector('.nc-lang-cnt');
const endinfo = await end.boundingBox();
await page.mouse.move(startinfo.x,endinfo.y);
await page.mouse.down();
for(var i=0;i<endinfo.width;i=i+5) {
await page.mouse.move(startinfo.x+i,endinfo.y);
}
await page.waitFor(3000)
await page.mouse.up();
//await brower.close();
})().catch(error =>{console.log('error')});

【PUPPETEER】初探之拖拽操作(五)的更多相关文章
- C#拖拽操作
C#的拖拽 本文将以Winform为例 有两个主要的事件: DragEnter 拖拽到区域中触发的事件 DragDrop 当拖拽落下的时候出发此事件 饮水思源 参考博客: http://www.cnb ...
- WPF 的拖拽操作(DragDrop)
在WPF中似乎没有对拖拽操作进行改变,和以前的方式一样.如果曾近在 Windows 窗体应用程序中使用过鼠标拖放,就会发现在 WPF 中的编程接口实际上没有发生变化.重要的区别是用于拖放操作的方法和事 ...
- 微信小程序~触摸相关事件(拖拽操作、手势识别、多点触控)
touchstart 手指触摸动作开始 touchmove 手指触摸后移动 touchcancel 手指触摸动作被打断,如来电提醒,弹窗 touchend 手指触摸动作结束 ...
- H5 拖拽操作
H5 拖拽操作 前言 在原生H5中,可以通过提供的api实现在网页内元素的拖拽操作.相对于传统的写法更加的简单. 而想要实现拖拽,主要需要进行两个方面的工作,第一是给元素设置draggable='tr ...
- selenium中各个模块操作:下拉框、鼠标悬浮连贯、拼图拖拽操作、以及其他拖拽操作、连线操作
1.下拉框的修改操作 方法一:定位到元素后,通过select选择对应的值 方法二:通过两次点击的方法:没有select的value属性时,采用click两次的方法去选择: click第一次后,出现下拉 ...
- MVC小系列(十五)【MVC+ZTree实现对树的CURD及拖拽操作】
根据上一讲的可以加载一棵大树,这讲讲下如果操作这颗大树 <link href="../../Scripts/JQuery-zTree/css/zTreeStyle/zTreeStyle ...
- 爱上MVC3~MVC+ZTree实现对树的CURD及拖拽操作
回到目录 上一讲中,我们学习了如何使用zTree对一棵大树(大数据量的树型结构的数据表,呵呵,名称有点绕,但说的是事实)进行异步加载,今天这讲,我们来说说,如何去操作这棵大树,无非就是添加子节点,删除 ...
- MVC+ZTree实现对树的CURD及拖拽操作
上一讲中,我们学习了如何使用zTree对一棵大树(大数据量的树型结构的数据表,呵呵,名称有点绕,但说的是事实)进行异步加载,今天这讲,我们来说说,如何去操作这棵大树,无非就是添加子节点,删除节点,编辑 ...
- javascript拖拽操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
随机推荐
- Java:基于TCP协议网络socket编程(实现C/S通信)
目录 一.前言:TCP原理简介 二.Socket编程通信 三.TCP服务器端(具体代码) 四.TCP客户端(具体代码) 五.通信效果演示 六."创意"机器人:价值一个亿的AI核心代 ...
- Jenkins自动化构建PHP实列教程
安装Jenkins 请参考群主的安装教程 进入jenkins,添加SSH server,并且安装gitlab,Generic Webhook Trigger Plugin,GitHub plugin, ...
- POI Excel 导入导出重点
HSSF是指2007年以前的,XSSF是指2007年版本以上的 这个还是比较好用的,这些总结来自Apache的官方向导的点点滴滴 详细的请参考http://poi.apache.org/spreads ...
- k8s部署之系统初始化(一)
初始化 1.安装依赖包 yum -y install tree lrzsz nmap nc telnet vim wget lsof network-tools bash-completion bas ...
- Linux 系统编程 学习:07-基于socket的网络编程2:基于 UDP 的通信
Linux 系统编程 学习:07-基于socket的网络编程2:基于 UDP 的通信 背景 上一讲我们介绍了网络编程的一些概念.socket的网络编程的有关概念 这一讲我们来看UDP 通信. 知识 U ...
- Java_进程与线程
进Process&Thread 区别 进程 线程 根本区别 作为资源分配的单位 调度和执行的单位 开销 每个进程都有独立的代码和数据空间(进程上下文), 进程间的切换会有较大的开销 线程可以看 ...
- 7. 基于MLlib的机器学习
*以下内容由<Spark快速大数据分析>整理所得. 读书笔记的第七部分是讲的是如何使用Spark中提供机器学习函数的MLlib库,在集群中并行运行机器学习算法. MLlib是Spark中提 ...
- 僵尸进程与SIGCHLD信号
什么是僵尸进程? 首先内核会释放终止进程(调用了exit系统调用)所使用的所有存储区,关闭所有打开的文件等,但内核为每一个终止子进程保存了一定量的信息.这些信息至少包括进程ID,进程的终止状态,以及该 ...
- close与shutdown
首先看一个例子,如下图所示: 当我们客户端发送ABCD再close套接字的时候,服务器端的接收通道也被关闭了,将无法接收ABCD的数据.如果想要仅仅关闭发送通道,保留接收通道,可以使用shutdown ...
- 从头学起Verilog(三):Verilog逻辑设计
引言 经过了组合逻辑和时序逻辑的复习,终于到了Verilog部分.这里主要介绍Verilog一些基础内容,包括结构化模型.TestBench编写和仿真.真值表模型. 这部分内容不多,也都十分基础,大家 ...