【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')});