PUPPETEER初探之拖拽操作

Posted totoro-cat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PUPPETEER初探之拖拽操作相关的知识,希望对你有一定的参考价值。

一、知识点

  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初探之拖拽操作的主要内容,如果未能解决你的问题,请参考以下文章

不同操作系统的 Puppeteer 安装

puppeteer截图

H5之拖拽

ios手势识别之拖拽

puppeteer的使用

Nodejs中puppeteer抓取浏览器HAR数据