使用puppeteer破解极验的滑动验证码

网友投稿 645 2023-02-16


使用puppeteer破解极验的滑动验证码

基本的流程:

1. 打开前端网,点击登录。

2. 填写账号,密码。

3. 点解验证按钮,通过滑动验证,最后成功登陆。

代码实现:

github上可以checkout。

具体代码如下所示:

run.js

const puppeteer = require('puppeteer');

const devices = require('puppeteer/DeviceDescriptors');

const iPhone = devices['iPhone 6 Plus'];

let timeout = function (delay) {

return new Promise((resolve, reject) => {

setTimeout(() => {

try {

resolve(1)

} catch (e) {

reject(0)

}

}, delay);

})

}

let page = null

let btn_position = null

let times = 0 // 执行重新滑动的次数

const distanceError = [-10,2,3,5] // 距离误差

async function run() {

const browser = await puppeteer.launch({

headless:false //这里我设置成false主要是为了让大家看到效果,设置为true就不会打开浏览器

});

page = await browser.newPage();

// 1.打开前端网

await page.emulate(iPhone);

await page.goto('https://qdfuns.com/');

await timeout(1000);

// 2.打开登录页面

page.click('a[data-type=login]')

await timeout(1000);

// 3.输入账号密码

page.type('input[data-type=email]','你的账号')

await timeout(500);

page.type('input[placeholder=密码]','你的密码')

await timeout(1000);

// 4.点击验证

page.click('.geetest_radar_tip')

await timeout(1000);

btn_position = await getBtnPosition();

// 5.滑动

drag(null)

}

/**

* 计算按钮需要滑动的距离

* */

async function calculateDistance() {

const distance = await page.evaluate(() => {

// 比较像素,找到缺口的大概位置

function compare(document) {

const ctx1 = document.querySelector('.geetest_canvas_fullbg'); // 完成图片

const ctx2 = document.querySelector('.geetest_canvas_bg'); // 带缺口图片

const pixelDifference = 30; // 像素差

let res = []; // 保存像素差较大的x坐标

// 对比像素

for(let i=57;i<260;i++){

for(let j=1;j<160;j++) {

const imgData1 = ctx1.getContext("2d").getImageData(1*i,1*j,1,1)

const imgData2 = ctx2.getContext("2d").getImageData(1*i,1*j,1,1)

const data1 = imgData1.data;

const data2 = imgData2.data;

const res1=Math.abs(data1[0]-data2[0]);

const res2=Math.abs(data1[1]-data2[1]);

const res3=Math.abs(data1[2]-data2[2]);

if(AOUxmg!(res1 < pixelDifference && res2 < pixelDifference && res3 < pixelDifference)) {

if(!res.includes(i)) {

res.push(i);

}

}

}

}

// 返回像素差最大值跟最小值,经过调试最小值往左小7像素,最大值往左54像素

return {min:res[0]-7,max:res[res.length-1]-54}

}

return compare(document)

})

return distance;

}

/**

* 计算滑块位置

*/

async function getBtnPosition() {

const btn_position = await page.evaluate(() => {

const {clientWidth,clientHeight} = document.querySelector('.geetest_popup_ghost')

return {btn_left:clientWidth/2-104,btn_top:clientHeight/2+59}

})

return btn_position;

}

/**

* 尝试滑动按钮

* @param distance 滑动距离

* */

async function tryValidation(distance) {

//将距离拆分成两段,模拟正常人的行为

const distance1 = distance - 10

const distance2 = 10

page.mouse.click(btn_position.btn_left,btn_position.btn_top,{delay:2000})

page.mouse.down(btn_position.btn_left,btn_position.btn_top)

page.mouse.move(btn_position.btn_left+distance1,btn_position.btn_top,{steps:30})

await timeout(800);

page.mouse.move(btn_position.btn_left+distance1+distance2,btn_position.btn_top,{steps:20})

await timeout(800);

page.mouse.up()

await timeout(4000);

// 判断是否验证成功

const isSuccess = await page.evaluate(() => {

return document.querySelector('.geetest_success_radar_tip_content') && document.querySelector('.geetest_success_radar_tip_content').innerHTML

})

await timeout(1000);

// 判断是否需要重新计算距离

const reDistance = await page.evaluate(() => {

return document.querySelector('.geetest_result_content') && document.querySelector('.geetest_result_content').innerHTML

})

await timeout(1000);

return {isSuccess:isSuccess==='验证成功',reDistance:reDistance.includes('怪物吃了拼图')}

}

/**

* 拖动滑块

* @param distance 滑动距离

* */

async function drag(distance) {

distance = distance || await calculateDistance();

const result = await tryValidation(distance.min)

if(result.isSuccess) {

await timeout(1000);

//登录

console.log('验证成功')

page.click('#modal-member-login button')

}else if(result.reDistance) {

console.log(AOUxmg'重新计算滑距离录,重新滑动')

times = 0

await drag(null)

} else {

if(distanceError[times]){

times ++

console.log('重新滑动')

await drag({min:distance.max,max:distance.max+distanceError[times]})

} else {

console.log('滑动失败')

times = 0

run()

}

}

}

run()

package.json

{

"name": "demo",

"version": "1.0.0",

"dependencies": {

"puppeteer": "^1.0.0"

}

}

运行

1. 将这个两个文件保存到文件夹下面,终端切换到当前路径下

2. npm i

3. 补上前端网的账号,密码

4. node run

演示

下图演示可以分为四步:

1. 打开登陆页面,输入事先写好的账号密码。

2. 第一次拖动滑块提示“被怪兽吃了”,所以重新计算了新的图片的缺口距离。

3. 第二,三次拖动提示“没正确合拼”,所以重新拖动。

4. 验证成功,登录。

(请将鼠标放到gif上查看演示效果,或者请拖到新窗口打开gif)

说明

1. 滑动验证有三个canvas,其中只需要 classname为‘geetest_canvas_fullbg'以及‘geetest_canvas_bg'的进行像素差对比。ps:前者是完整图片,后者是带缺口的图片。

2. 每个带缺口的图片都有一块误导的阴影,所以对比像素差的时候,计算出的距离分别是误导阴影以及缺口的。因此,滑动距离的取值,我取‘{min:res[0]-7,max:res[res.length-1]-54}'。当缺口比误导阴影靠左时, min(距离最小值) 值就是滑动距离,否则就是 max(距离最大值)减去滑块宽度 。

3. 滑动结果分三种情况:验证成功,被吃了,失败。 “被吃了” 会重新请求图片,所以重新计算了距离再滑动; “失败” 则重新滑动,如果执行 4 次依然失败,则重新run整个流程。

总结

以上所述是给大家介绍的使用puppeteer破解极验的滑动验证码,希望对大家有所帮助,如果大家有任何疑问请给我留言,会及时回复大家的。在此也非常感谢大家对我们网站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:api接口管理总结(api审核总结)
下一篇:三种Java求最大值的方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~