说到滑动验证码,大家想到的就是通过无头浏览器,模拟手势滑动。
但是这个过程有两个重要的点。突破了这两个点,滑动验证码就可以很轻松的绕过了。
阅读流程
-
效果
-
代码
-
滑动中的两个关键点
-
总结
效果
代码
话不多说,直接上代码。
var puppeteer = require('puppeteer')
const devices = require('puppeteer/DeviceDescriptors');
const iphone = devices['iPhone 6']
const conf = {
headless: false,
defaultViewport: {
width: 1300,
height: 900
},
slowMo: 30
}
puppeteer.launch(conf).then(async browser => {
var page = await browser.newPage()
await page.emulate(iphone)
await page.goto('https://www.dingtalk.com/oasite/register_h5_new.htm')
//关键点1
await page.evaluate(async () => {
Object.defineProperty(navigator, 'webdriver', {get: () => false})
})
// 错误输入,触发验证码
await page.type('#mobileReal', '176112628161')
await page.click('#dingapp > div > div > div > div > div._38BOT4Nk > a')
await page.type('#mobileReal', '')
await page.keyboard.press('Backspace')
await page.click('._2q5FIy80')
// 等待滑块出现
var slide_btn = await page.waitForSelector('#nc_1_n1t', {timeout: 30000})
// 计算滑块距离
const rect = await page.evaluate((slide_btn) => {
const {top, left, bottom, right} = slide_btn.getBoundingClientRect();
return {top, left, bottom, right}
}, slide_btn)
console.log(rect)
rect.left = rect.left + 10
rect.top = rect.top + 10
const mouse = page.mouse
await mouse.move(rect.left, rect.top)
// 关键点2
await page.touchscreen.tap(rect.left, rect.top) // h5需要手动分发事件 模拟app的事件分发机制。
await mouse.down()
var start_time = new Date().getTime()
await mouse.move(rect.left + 800, rect.top, {steps: 25})
await page.touchscreen.tap(rect.left + 800, rect.top,)
console.log(new Date().getTime() - start_time)
await mouse.up()
console.log(await page.evaluate('navigator.webdriver'))
console.log('end')
// await page.close()
})
滑动中的两个关键点
代码的两个重要点
众所周知,滑动验证码会检测nabigator.webdriver这个属性。因此我们需要在滑动前将这个属性设置为false
await page.evaluate(async () => {
Object.defineProperty(navigator, 'webdriver', {get: () => false})
})
h5滑块的事件是:touchevent,而puppeteer只有mouseevent。因此需要通过某个方法,在滑动前先将事件传递出去。这个类似android的事件分发,android事件分发可以在我博客查看,这里不细说。
await page.touchscreen.tap(rect.left, rect.top)
ok,具备了两点,上面的滑动验证码就能成功了。
总结
从钉钉注册这个例子来看,阿里的滑块操作仅仅是下面步骤。
找到滑块,计算滑块位置,分发事件,拖动,松手。
后记
我问了下作者为什么不用python版本的pyppeteer呢,
作者回应:使用python版的pyppeteer测试滑动验证码的时候,崩溃率/失败率极高。而用node原生的,成功率几乎100%。 原因主要还是pyppeteer是非官方的,其稳定性比起官方版的puppeteer差很多,而且容易奔溃。所在在使用pyppeteer失败的情况下可以试试node里的puppeteer。排除代码的问题
对原文稍作改动。
原文作者:阳光下的小树
原文来源:https://blog.youkuaiyun.com/u013356254/article/details/88564342