目標
處理存在淘寶滑塊驗證碼,並封裝成爲工具類。。。。
主要學習以下知識點
方法名稱 | 方法說明 |
---|---|
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