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

安装Rust和相关库
首先,你需要安装Rust编译器和包管理工具Cargo。如果你还没有安装,可以访问 Rust官网 进行安装。

接下来,我们需要安装chromiumoxide库和OpenCV的Rust绑定opencv库。

在项目目录下创建一个新的Rust项目:

sh

cargo new captcha_solver
cd captcha_solver
然后,在Cargo.toml文件中添加以下依赖:

toml

[dependencies]
chromiumoxide = "0.2"
opencv = "0.54"
tokio = { version = "1", features = ["full"] }
验证码页面
验证码页面地址:https://dun.163.com/trial/jigsaw

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

rust

use chromiumoxide::browser::{Browser, BrowserConfig};
use chromiumoxide::cdp::browser_protocol::page::ScreenshotFormat;
use chromiumoxide::cdp::browser_protocol::page::Viewport;
use chromiumoxide::Page;
use tokio;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (browser, mut handler) = Browser::launch(
        BrowserConfig::builder().build()?
    ).await?;
    
    let page = browser.new_page("https://dun.163.com/trial/jigsaw").await?;

    // 等待页面加载完成
    tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;

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

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

rust

use std::fs::File;
use std::io::Write;

async fn get_image(page: &Page, selector: &str, file_path: &str) -> Result<(), Box<dyn std::error::Error>> {
    let js_code = format!(r#"
        document.querySelector("{}").src;
    "#, selector);

    let image_url: String = page.evaluate(js_code).await?.into_value()?;
    let response = reqwest::get(&image_url).await?;
    let mut file = File::create(file_path)?;
    let content = response.bytes().await?;
    file.write_all(&content)?;
    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (browser, mut handler) = Browser::launch(
        BrowserConfig::builder().build()?
    ).await?;
    
    let page = browser.new_page("https://dun.163.com/trial/jigsaw").await?;
    tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;

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

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

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

rust

use opencv::core::{Mat, Point, Scalar, Size, CV_8UC1, CV_32FC1};
use opencv::imgcodecs::{imread, IMREAD_COLOR};
use opencv::imgproc::{cvt_color, match_template, min_max_loc, COLOR_BGR2GRAY, TM_CCOEFF_NORMED};

fn get_slide_distance() -> Result<i32, Box<dyn std::error::Error>> {
    let bg_image = imread("bg.png", IMREAD_COLOR)?;
    let puzzle_image = imread("puzzle.png", IMREAD_COLOR)?;

    let mut gray_bg = Mat::default()?;
    cvt_color(&bg_image, &mut gray_bg, COLOR_BGR2GRAY, 0)?;

    let mut gray_puzzle = Mat::default()?;
    cvt_color(&puzzle_image, &mut gray_puzzle, COLOR_BGR2GRAY, 0)?;

    let mut result = Mat::new_size(gray_bg.size()?, CV_32FC1)?;
    match_template(&gray_bg, &gray_puzzle, &mut result, TM_CCOEFF_NORMED, &Mat::default()?)?;

    let mut min_val = 0.0;
    let mut max_val = 0.0;
    let mut min_loc = Point::default();
    let mut max_loc = Point::default();
    min_max_loc(&result, Some(&mut min_val), Some(&mut max_val), Some(&mut min_loc), Some(&mut max_loc), &Mat::default()?)?;

    Ok(max_loc.x)
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (browser, mut handler) = Browser::launch(
        BrowserConfig::builder().build()?
    ).await?;
    
    let page = browser.new_page("https://dun.163.com/trial/jigsaw").await?;
    tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;

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

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

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

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

rust

use chromiumoxide::cdp::browser_protocol::input::{dispatch_mouse_event, MouseButton};

async fn slide_puzzle(page: &Page, distance: i32) -> Result<(), Box<dyn std::error::Error>> {
    let slider = page.find_element(".yidun_slider").await?;
    let bounding_box = slider.bounding_box().await?.unwrap();
    let start_x = bounding_box.x + bounding_box.width / 2.0;
    let start_y = bounding_box.y + bounding_box.height / 2.0;

    page.dispatch_mouse_event(dispatch_mouse_event::Type::MouseMoved, start_x, start_y).await?;
    page.dispatch_mouse_event(dispatch_mouse_event::Type::MousePressed, start_x, start_y)
        .button(MouseButton::Left)
        .click_count(1)
        .await?;

    let steps = 30;
    let move_x = distance as f64 / steps as f64;
    for i in 0..steps {
        let current_x = start_x + i as f64 * move_x;
        page.dispatch_mouse_event(dispatch_mouse_event::Type::MouseMoved, current_x, start_y).await?;
        tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
    }

    page.dispatch_mouse_event(dispatch_mouse_event::Type::MouseReleased, start_x + distance as f64, start_y)
        .button(MouseButton::Left)
        .click_count(1)
        .await?;
    
    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let (browser, mut handler) = Browser::launch(
        BrowserConfig::builder().build()?
    ).await?;
    
    let page = browser.new_page("https://dun.163.com/trial/jigsaw").await?;
    tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;

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

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

    slide_puzzle(&page, distance).await?;

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

    Ok(())
}更多内容联系q1436423940

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值