使用JavaScript和Puppeteer破解滑动验证码

滑动验证码是一种常见的验证码形式,通过拖动滑块将缺失的拼图块对准原图中的空缺位置来验证用户操作。本文将介绍如何使用JavaScript中的OpenCV进行模板匹配,并结合Puppeteer实现自动化破解滑动验证码的过程。

所需技术
OpenCV模板匹配:用于识别滑块在背景图中的正确位置。
JavaScript:主要编程语言。
Puppeteer:用于浏览器自动化,模拟用户操作。
破解过程概述
获取验证码图像:
下载背景图和滑块图。
进行必要的图像预处理。
模板匹配:
使用OpenCV的模板匹配算法,计算滑块在背景图中的最佳匹配位置。
模拟滑动:
生成模拟人类滑动的轨迹,避免被识别为机器人。
使用Puppeteer模拟滑动操作。
实现步骤
1. 设置环境
首先,我们需要设置Node.js环境并安装相关的依赖包。

sh

npm init -y
npm install puppeteer opencv4nodejs
2. 获取并预处理验证码图像
接下来,编写JavaScript代码,下载验证码的背景图和滑块图,并对图像进行预处理。

javascript

const puppeteer = require('puppeteer');
const cv = require('opencv4nodejs');
const fs = require('fs');
const axios = require('axios');

async function getImages(bgUrl, sliderUrl) {
    const bgResponse = await axios.get(bgUrl, { responseType: 'arraybuffer' });
    const sliderResponse = await axios.get(sliderUrl, { responseType: 'arraybuffer' });

    fs.writeFileSync('background.png', bgResponse.data);
    fs.writeFileSync('slider.png', sliderResponse.data);
}

function preprocessImages() {
    const bgImg = cv.imread('background.png');
    const sliderImg = cv.imread('slider.png', cv.IMREAD_GRAYSCALE);

    return { bgImg, sliderImg };
}
在上述代码中,我们下载并保存验证码图像,然后将滑块图转换为灰度图进行处理。

3. 模板匹配
使用OpenCV的模板匹配算法来确定滑块在背景图中的正确位置。

javascript

function findSliderPosition(bgImg, sliderImg) {
    const result = bgImg.matchTemplate(sliderImg, cv.TM_CCOEFF_NORMED);
    const minMax = result.minMaxLoc();
    const { maxLoc: top_left } = minMax;

    return top_left.x;
}

(async () => {
    const bgUrl = 'background_image_url';
    const sliderUrl = 'slider_image_url';

    await getImages(bgUrl, sliderUrl);
    const { bgImg, sliderImg } = preprocessImages();
    const sliderPosition = findSliderPosition(bgImg, sliderImg);

    console.log('Slider Position:', sliderPosition);
})();
这里我们使用TM_CCOEFF_NORMED算法进行匹配,并找到最佳匹配位置的坐标。

4. 模拟滑动操作
通过生成一条模拟人类滑动的轨迹,并使用Puppeteer模拟滑动操作。

javascript

function generateTrack(distance) {
    const track = [];
    let current = 0;
    const mid = distance * 4 / 5;
    let t = 0.2;
    let v = 0;

    while (current < distance) {
        let a = current < mid ? 2 : -3;
        let v0 = v;
        v = v0 + a * t;
        let move = v0 * t + 0.5 * a * t * t;
        current += move;
        track.push(Math.round(move));
    }

    return track;
}

async function simulateSliderMove(page, slider, track) {
    await page.click(slider, { delay: 200 });

    const sliderHandle = await page.$(slider);
    const boundingBox = await sliderHandle.boundingBox();

    await page.mouse.move(
        boundingBox.x + boundingBox.width / 2,
        boundingBox.y + boundingBox.height / 2
    );

    await page.mouse.down();

    for (const move of track) {
        await page.mouse.move(
            boundingBox.x + move,
            boundingBox.y + boundingBox.height / 2,
            { steps: 10 }
        );
        await page.waitForTimeout(20 + Math.random() * 10);
    }

    await page.mouse.up();
}

(async () => {
    const browser = await puppeteer.launch({ headless: false });
    const page = await browser.newPage();
    await page.goto('your_target_website_with_captcha');

    const slider = 'your_slider_css_selector';
    const sliderPosition = 100; // Assume we got this from the template matching
    const track = generateTrack(sliderPosition);

    await simulateSliderMove(page, slider, track);

    await browser.close();
})();

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值