使用Rust破解网易易盾滑动验证码


准备工作
安装Rust和相关库
首先,你需要安装Rust。如果你还没有安装,可以访问Rust官网进行安装。

接下来,我们需要安装Selenium的Rust客户端库fantoccini和OpenCV的Rust绑定库opencv.

在终端中运行以下命令安装依赖:

sh

cargo new yidun_crack
cd yidun_crack
cargo add fantoccini
cargo add opencv
验证码页面
验证码页面地址:https://dun.163.com/trial/jigsaw

代码实现
1. 初始化Selenium
我们首先启动Selenium WebDriver并导航到验证码页面。

rust

use fantoccini::{Client, Locator};
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let client = Client::new("http://localhost:4444").await?;

    // 打开目标网页
    client.goto("https://dun.163.com/trial/jigsaw").await?;

    // 延迟加载以确保页面加载完全
    tokio::time::sleep(std::time::Duration::from_secs(3)).await;

    // 后续的验证码处理代码将放在这里

    client.close().await?;
    Ok(())
}
2. 获取验证码图片
获取验证码图片并保存到本地,以便使用OpenCV进行图像处理。

rust

use fantoccini::Client;
use std::error::Error;
use std::fs::File;
use std::io::Write;
use reqwest;

async fn get_image(client: &Client, selector: &str, file_path: &str) -> Result<(), Box<dyn Error>> {
    let elem = client.find(Locator::Css(selector)).await?;
    let img_url = elem.attr("src").await?.ok_or("No src attribute")?;

    let response = reqwest::get(&img_url).await?;
    let bytes = response.bytes().await?;

    let mut file = File::create(file_path)?;
    file.write_all(&bytes)?;

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let client = Client::new("http://localhost:4444").await?;

    client.goto("https://dun.163.com/trial/jigsaw").await?;
    tokio::time::sleep(std::time::Duration::from_secs(3)).await;

    get_image(&client, ".yidun_bg-img", "bg.png").await?;
    get_image(&client, ".yidun_jigsaw", "puzzle.png").await?;

    // 后续的验证码处理代码将放在这里

    client.close().await?;
    Ok(())
}
3. 使用OpenCV匹配图像
使用OpenCV找到拼图缺口的位置。

rust

use opencv::core::{Point, Rect, Scalar, Size, CV_8UC1};
use opencv::imgcodecs::{imread, imwrite, IMREAD_COLOR, IMREAD_GRAYSCALE};
use opencv::imgproc::{cvt_color, match_template, tm_sqdiff_normed};
use opencv::prelude::*;

fn get_slide_distance(bg_path: &str, puzzle_path: &str) -> Result<f64, Box<dyn Error>> {
    let bg_img = imread(bg_path, IMREAD_COLOR)?;
    let puzzle_img = imread(puzzle_path, IMREAD_COLOR)?;

    let mut result = Mat::default()?;
    let result_cols = bg_img.cols() - puzzle_img.cols() + 1;
    let result_rows = bg_img.rows() - puzzle_img.rows() + 1;
    let size = Size::new(result_cols, result_rows);
    result.create(size, CV_8UC1)?;

    match_template(&bg_img, &puzzle_img, &mut result, tm_sqdiff_normed, &Mat::default())?;

    let min_max_loc = opencv::core::min_max_loc(&result, None, None, None, None)?;

    Ok(min_max_loc.min_loc.x as f64)
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let client = Client::new("http://localhost:4444").await?;

    client.goto("https://dun.163.com/trial/jigsaw").await?;
    tokio::time::sleep(std::time::Duration::from_secs(3)).await;

    get_image(&client, ".yidun_bg-img", "bg.png").await?;
    get_image(&client, ".yidun_jigsaw", "puzzle.png").await?;

    let distance = get_slide_distance("bg.png", "puzzle.png")?;
    println!("Slide distance: {}", distance);

    // 后续的验证码处理代码将放在这里

    client.close().await?;
    Ok(())
}
4. 模拟滑动行为
模拟人类滑动行为,以避免被检测为机器人。

rust

use rand::Rng;
use std::time::Duration;

async fn slide_puzzle(client: &Client, distance: f64) -> Result<(), Box<dyn Error>> {
    let slider = client.find(Locator::Css(".yidun_slider")).await?;
    let rect = slider.rect().await?;

    let start_x = rect.x + rect.width / 2;
    let start_y = rect.y + rect.height / 2;

    client.mouse_move_to_location(Some((start_x as f64, start_y as f64))).await?;
    client.mouse_down().await?;

    let steps = 30;
    let move_x = distance / steps as f64;

    let mut rng = rand::thread_rng();

    for i in 0..steps {
        let current_x = start_x as f64 + move_x * i as f64;
        client.mouse_move_to_location(Some((current_x, start_y as f64))).await?;
        tokio::time::sleep(Duration::from_millis(100 + rng.gen_range(0..50))).await;
    }

    client.mouse_up().await?;

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {更多内容联系1436423940

    let client = Client::new("http://localhost:4444").await?;

    client.goto("https://dun.163.com/trial/jigsaw").await?;
    tokio::time::sleep(std::time::Duration::from_secs(3)).await;

    get_image(&client, ".yidun_bg-img", "bg.png").await?;
    get_image(&client, ".yidun_jigsaw", "puzzle.png").await?;

    let distance = get_slide_distance("bg.png", "puzzle.png")?;
    println!("Slide distance: {}", distance);

    slide_puzzle(&client, distance).await?;

    tokio::time::sleep(Duration::from_secs(5)).await;

    client.close().await?;
    Ok(())
}

  • 19
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值