处理存在淘宝滑块验证码,并封装成为工具类。。。。
方法名称 | 方法说明 |
---|---|
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.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