puppeteer 教程(11) ----进阶(puppeteer 处理淘宝滑块验证码)

目标

处理存在淘宝滑块验证码,并封装成为工具类。。。。

主要学习以下知识点

方法名称 方法说明
page.evaluateOnNewDocument 添加一个方法,在以下某个场景被调用:1.页面导航完成后,2.页面的iframe加载或导航完成。这种场景,指定的函数被调用的上下文是新加载的iframe。
page.mouse.move 触发一个 mousemove 事件。
page.mouse.down 触发一个 mousedown 事件。
mouse.up([options]) 触发一个 mouseup 事件。

详细api 可参考
https://blog.csdn.net/mengxiangxingdong/article/details/99237204

开始

本文章代码均在 上传在
https://gitee.com/hugo110/puppeteer-demo
效果图
puppeteer 教程(11) ----进阶(puppeteer 处理淘宝滑块验证码)_第1张图片

1.代码

1.1.taobao_verify_code_20191014

/*

模拟登陆 51  cto
https://home.51cto.com/index
 */


/*

模拟登陆 csdn
https://blog.csdn.net/mengxiangxingdong
 */
/**
 * 第三方库
 */
const puppeteer = require('puppeteer'); //引入puppeteer库


/**
 * 本地库
 */
const {installMouseHelper} = require('./util/install-mouse-helper');
const captchaBehaviorUtil = require('./util/CaptchaBehaviorUtil');


const xpathUtil = require('./util/XpathUtil');
(async () => {
    const browser = await puppeteer.launch({    //启动浏览器
        args: ['--no-sandbox'],
        headless: false,   //代码运行时打开浏览器方便观察
        // slowMo: 300  //放慢速度
        // devtools:true   //打开f12界面
    });
    const page = await browser.newPage();  //打开浏览器的一个tab 页
    // Installs the helper to the page. Mouse will be visible in the subsequent navigation.
    await installMouseHelper(page); //调试鼠标轨迹专用

    await page.goto('https://www.etax-gd.gov.cn/xxmh/html/index.html', {timeout: 20 * 1000, waitUntil: 'networkidle0'});
    //等待登录元素出现

    await page.waitForSelector('.loginico', {timeout: 20 * 1000}).then(elementHandle => {
        elementHandle.click();
        // elementHandle.dispose();
    }).catch(e => console.log(e));
    // page.waitForNavigation({timeout: 10 * 1000, waitUntil: 'networkidle0'}).catch(e => console.log(e));
    // await page.waitFor(3 * 1000);

    await page.waitForXPath('//a[contains(string(),"下次再说")]', {
        timeout: 20 * 1000,
        visible: true
    })
    /*        .then(elementHandle => {
            elementHandle.click();
            // elementHandle.dispose();
        })*/
        .catch(e => console.log(e));

    await page.waitFor(1 * 1000); //等待广告弹出
    await xpathUtil.$xClick(page, '//a[contains(string(),"下次再说")]');
    await page.waitFor(3 * 1000);

    //淘宝验证码
    await  captchaBehaviorUtil.taobao(page);


    // await browser.close();  //关闭浏览器
})();

1.2install-mouse-helper.js

/**
 * // This injects a box into the page that moves with the mouse;
 // Useful for debugging
 调试鼠标轨迹专用
 */

async function installMouseHelper(page) {
    await page.evaluateOnNewDocument(() => {
        // Install mouse helper only for top-level frame.
        if (window !== window.parent)
            return;
        window.addEventListener('DOMContentLoaded', () => {
            const box = document.createElement('puppeteer-mouse-pointer');
            const styleElement = document.createElement('style');
            styleElement.innerHTML = `
        puppeteer-mouse-pointer {
          pointer-events: none;
          position: absolute;
          top: 0;
          z-index: 10000;
          left: 0;
          width: 20px;
          height: 20px;
          background: rgba(0,0,0,.4);
          border: 1px solid white;
          border-radius: 10px;
          margin: -10px 0 0 -10px;
          padding: 0;
          transition: background .2s, border-radius .2s, border-color .2s;
        }
        puppeteer-mouse-pointer.button-1 {
          transition: none;
          background: rgba(0,0,0,0.9);
        }
        puppeteer-mouse-pointer.button-2 {
          transition: none;
          border-color: rgba(0,0,255,0.9);
        }
        puppeteer-mouse-pointer.button-3 {
          transition: none;
          border-radius: 4px;
        }
        puppeteer-mouse-pointer.button-4 {
          transition: none;
          border-color: rgba(255,0,0,0.9);
        }
        puppeteer-mouse-pointer.button-5 {
          transition: none;
          border-color: rgba(0,255,0,0.9);
        }
      `;
            document.head.appendChild(styleElement);
            document.body.appendChild(box);
            document.addEventListener('mousemove', event => {
                box.style.left = event.pageX + 'px';
                box.style.top = event.pageY + 'px';
                updateButtons(event.buttons);
            }, true);
            document.addEventListener('mousedown', event => {
                updateButtons(event.buttons);
                box.classList.add('button-' + event.which);
            }, true);
            document.addEventListener('mouseup', event => {
                updateButtons(event.buttons);
                box.classList.remove('button-' + event.which);
            }, true);

            function updateButtons(buttons) {
                for (let i = 0; i < 5; i++)
                    box.classList.toggle('button-' + i, buttons & (1 << i));
            }
        }, false);
    });
};

module.exports = {installMouseHelper};

CaptchaBehaviorUtil.js 后面陆续添加 极验等等

/**
 * 市面上常用的验证码破解
 */

async function taobao(page) {
    console.log('验证码start')
    await page.evaluate(async () => {
        Object.defineProperty(navigator, 'webdriver', {get: () => false})
    })
// 等待滑块出现
    var slide_btn = await page.waitForSelector('#nc_1_n1t', {timeout: 30 * 1000}).catch(e => {
        console.log("淘宝--滑块验证码不存在");
        console.log(e);
    })
    // 计算滑块距离
    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, {steps: 1})
    // await simulateMove(page, rect.left, rect.top, {steps: 1})
    // 关键点2
    await page.touchscreen.tap(rect.left, rect.top) // h5需要手动分发事件 模拟app的事件分发机制。
    await mouse.down()

    let number = await randomInt(400, 800);

    await simulateMove(page, rect.left, rect.top, rect.right + number, rect.bottom, {steps: 1})

    await page.touchscreen.tap(rect.right + number, rect.bottom);
    await mouse.up()
    console.log("淘宝反自动化识别====" + await page.evaluate('navigator.webdriver'))
    console.log('验证码end')
}

/**
 * 随机轨迹移动
 * @param page
 * @returns {Promise}
 */
async function simulateMove(page, startX, startY, endX, endY, options = {}) {
    const mouse = page.mouse;
    //随机移动 5次以内  随机长度
    let len = await randomInt(5);
    let xNumber = await endX;
    let currentX = 0;
    let xTemp = await randomInt(endX - startX);
    let yTemp = await  startY + randomInt(5); //下幅度20内  y轴的改变不影响
    for (let i = 0; i < len; i++) {
        await mouse.move(currentX + xTemp, yTemp, options)
        currentX = await xTemp + currentX;
        xTemp = await randomInt(endX - startX);
        xNumber = await xNumber - xTemp;
        // await  page.waitFor(await randomInt(100, 20));
    }
    //补偿一个直接移动
    await mouse.move(startX + xTemp, endX);
    if (xNumber - startX > 0) {
        await mouse.move(xNumber, yTemp, options);
    }
}

/**
 *  random  范围  (minNumber,maxNumber];   minNumber 默认0
 * @param i
 * @returns {number}
 */
function randomInt(maxNumber, minNumber) {
    if (!minNumber) {
        minNumber = 0;
    }
    return Math.round(Math.random() * maxNumber) + 1 + minNumber;
}

module.exports = {
    taobao,
}

参考博客

https://zhaoqize.github.io/puppeteer-api-zh_CN/#?product=Puppeteer&version=v1.19.0&show=api-pageevalselector-pagefunction-args-1

https://blog.csdn.net/u013356254/article/details/88564342

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect

你可能感兴趣的:(【爬虫】,puppeteer,教程)