爬虫实战之puppeteer破解阿里h5滑动验证码

说到滑动验证码,大家想到的就是通过无头浏览器,模拟手势滑动。
但是这个过程有两个重要的点。突破了这两个点,滑动验证码就可以很轻松的绕过了。

阅读流程

  • 效果

  • 代码

  • 滑动中的两个关键点

  • 总结

效果

爬虫实战之puppeteer破解阿里h5滑动验证码_第1张图片

代码

话不多说,直接上代码。

    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.csdn.net/u013356254/article/details/88564342 

你可能感兴趣的:(技术)