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
效果圖
在這裏插入圖片描述

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<void>}
 */
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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章