知识点
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’]
});
三、实例
-
登入大麦网,我们今天来注册一下,但是发现他需要滑动验证,那么我们来试一下
-
如何定位,如何切换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');
复制代码
- 定位到滑动块 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();
- 分析下面该怎么做,首先我们获取了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')});
复制代码