一、知识点

  1. page.mouse
  2. elementHandle.boundingBox()
  3. ignoreDefaultArgs:['--enable-automation']  
  4. 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】初探之拖拽操作(五)的更多相关文章

  1. C#拖拽操作

    C#的拖拽 本文将以Winform为例 有两个主要的事件: DragEnter 拖拽到区域中触发的事件 DragDrop 当拖拽落下的时候出发此事件 饮水思源 参考博客: http://www.cnb ...

  2. WPF 的拖拽操作(DragDrop)

    在WPF中似乎没有对拖拽操作进行改变,和以前的方式一样.如果曾近在 Windows 窗体应用程序中使用过鼠标拖放,就会发现在 WPF 中的编程接口实际上没有发生变化.重要的区别是用于拖放操作的方法和事 ...

  3. 微信小程序~触摸相关事件(拖拽操作、手势识别、多点触控)

    touchstart     手指触摸动作开始 touchmove    手指触摸后移动 touchcancel  手指触摸动作被打断,如来电提醒,弹窗 touchend      手指触摸动作结束 ...

  4. H5 拖拽操作

    H5 拖拽操作 前言 在原生H5中,可以通过提供的api实现在网页内元素的拖拽操作.相对于传统的写法更加的简单. 而想要实现拖拽,主要需要进行两个方面的工作,第一是给元素设置draggable='tr ...

  5. selenium中各个模块操作:下拉框、鼠标悬浮连贯、拼图拖拽操作、以及其他拖拽操作、连线操作

    1.下拉框的修改操作 方法一:定位到元素后,通过select选择对应的值 方法二:通过两次点击的方法:没有select的value属性时,采用click两次的方法去选择: click第一次后,出现下拉 ...

  6. MVC小系列(十五)【MVC+ZTree实现对树的CURD及拖拽操作】

    根据上一讲的可以加载一棵大树,这讲讲下如果操作这颗大树 <link href="../../Scripts/JQuery-zTree/css/zTreeStyle/zTreeStyle ...

  7. 爱上MVC3~MVC+ZTree实现对树的CURD及拖拽操作

    回到目录 上一讲中,我们学习了如何使用zTree对一棵大树(大数据量的树型结构的数据表,呵呵,名称有点绕,但说的是事实)进行异步加载,今天这讲,我们来说说,如何去操作这棵大树,无非就是添加子节点,删除 ...

  8. MVC+ZTree实现对树的CURD及拖拽操作

    上一讲中,我们学习了如何使用zTree对一棵大树(大数据量的树型结构的数据表,呵呵,名称有点绕,但说的是事实)进行异步加载,今天这讲,我们来说说,如何去操作这棵大树,无非就是添加子节点,删除节点,编辑 ...

  9. javascript拖拽操作

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

随机推荐

  1. Spring Cloud Alibaba Seata

    一.简介 官网地址:http://seata.io/zh-cn/ 1,概念 Seata是一款开源的分布式事务解决方案,致力于在微服务架构在提供高性能和简单一样的分布式事务服务. 2,处理过程 Tran ...

  2. linux中nginx中配置端口转发

    域名指向主机IP地址,通过域名:8080才能访问网站,去掉后面的8080:或者其他的端口号,直接使用域名访问网站 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处 ...

  3. 输出5个大写英文字母的组合,并写入到txt文档中,随机数法。

    1.问题起源:最近想申请几个英文商标,研究了一下,英文字母在4到7个之间最好,5个字母尤佳,所以先来输出5个字母的组合,可是想像力有限,于是想用排列组合把所有5个可能的字母组合都输出,再从中挑选几个感 ...

  4. Kubernetes 搭建 ES 集群(存储使用 cephfs)

    一.集群规划 使用 cephfs 实现分布式存储和数据持久化 ES 集群的 master 节点至少需要三个,防止脑裂. 由于 master 在配置过程中需要保证主机名固定和唯一,所以搭建 master ...

  5. python数据类型之dict(字典)

    dict字典 关注公众号"轻松学编程"了解更多. 1.概述 dict也是一种存储方式,类似于list和tuple,但是,字典采用键-值(key-value)的形式存储. 优点:具有 ...

  6. Servlet学习笔记(二)

    目录 Servlet学习笔记(二) Request对象 1.request和response对象: 2.request对象继承体系结构: 3.什么是HttpServletRequest ? 4.Htt ...

  7. 【SpringBoot】05.SpringBoot整合Listener的两种方式

    SpringBoot整合Listener的两种方式: 1.通过注解扫描完成Listener组件的注册 创建一个类实现ServletContextListener (具体实现哪个Listener根据情况 ...

  8. 使用Python虚拟环境

    python 的虚拟环境可以为一个 python 项目提供独立的解释环境.依赖包等资源,既能够很好的隔离不同项目使用不同 python 版本带来的冲突,而且还能方便项目的发布. virtualenv ...

  9. Pycharm激活码无偿分享,2020年最新Pycharm永久激活码!

    2020年10月7日08:04:34更新的Pycharm激活码,还热乎着呢,速用~ 如果下边的这个Pycharm激活码过期失效了的话,大家可以关注我的微信公众号:Python联盟,然后回复" ...

  10. 年轻人不讲武德来白piao我这个老同志

    朋友们好啊,我是码农小胖哥. 今天有个同学问我在吗,我说什么事? 给我发个截图,我一看!噢,原来是帮忙搞个定时任务,还是动态的. 他说了两种选择,一种是用DelayQueue,一种是用消息队列. 他说 ...