使用Go和Rod破解滑动验证码


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

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

sh

go get -u github.com/go-rod/rod
go get -u gocv.io/x/gocv
2. 获取并预处理验证码图像
编写Go代码,下载验证码的背景图和滑块图,并对图像进行预处理。

go

package main

import (
    "gocv.io/x/gocv"
    "image"
    "io"
    "net/http"
    "os"
)

func downloadImage(url, filename string) error {
    resp, err := http.Get(url)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    file, err := os.Create(filename)
    if err != nil {
        return err
    }
    defer file.Close()

    _, err = io.Copy(file, resp.Body)
    return err
}

func preprocessImages(bgPath, sliderPath string) (gocv.Mat, gocv.Mat) {
    bgImg := gocv.IMRead(bgPath, gocv.IMReadColor)
    sliderImg := gocv.IMRead(sliderPath, gocv.IMReadGrayScale)
    return bgImg, sliderImg
}

func main() {
    bgURL := "background_image_url"
    sliderURL := "slider_image_url"
    downloadImage(bgURL, "background.png")
    downloadImage(sliderURL, "slider.png")

    bgImg, sliderImg := preprocessImages("background.png", "slider.png")
    defer bgImg.Close()
    defer sliderImg.Close()

    // Next steps will be here
}
在上述代码中,我们下载并保存验证码图像,然后将滑块图转换为灰度图进行处理。

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


func findSliderPosition(bgImg, sliderImg gocv.Mat) int {
    result := gocv.NewMat()
    defer result.Close()

    gocv.MatchTemplate(bgImg, sliderImg, &result, gocv.TmCcoeffNormed, gocv.NewMat())
    _, _, _, maxLoc := gocv.MinMaxLoc(result)
    return maxLoc.X
}

func main() {
    bgURL := "background_image_url"
    sliderURL := "slider_image_url"
    downloadImage(bgURL, "background.png")
    downloadImage(sliderURL, "slider.png")

    bgImg, sliderImg := preprocessImages("background.png", "slider.png")
    defer bgImg.Close()
    defer sliderImg.Close()

    sliderPosition := findSliderPosition(bgImg, sliderImg)
    println("Slider Position:", sliderPosition)

    // Next steps will be here
}
这里我们使用TmCcoeffNormed算法进行匹配,并找到最佳匹配位置的坐标。

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


package main

import (
    "context"
    "github.com/go-rod/rod"
    "github.com/go-rod/rod/lib/input"
    "math"
    "math/rand"
    "time"
)

func generateTrack(distance int) []int {
    var track []int
    current := 0
    mid := distance * 4 / 5
    t := 0.2
    v := 0.0

    for current < distance {
        var a int
        if current < mid {
            a = 2
        } else {
            a = -3
        }
        v0 := v
        v = v0 + float64(a)*t
        move := v0*t + 0.5*float64(a)*t*t
        current += int(math.Round(move))
        track = append(track, int(math.Round(move)))
    }

    return track
}

func main() {
    bgURL := "background_image_url"
    sliderURL := "slider_image_url"
    downloadImage(bgURL, "background.png")
    downloadImage(sliderURL, "slider.png")

    bgImg, sliderImg := preprocessImages("background.png", "slider.png")
    defer bgImg.Close()
    defer sliderImg.Close()

    sliderPosition := findSliderPosition(bgImg, sliderImg)
    println("Slider Position:", sliderPosition)

    page := rod.New().MustConnect().MustPage("your_target_website_with_captcha")
    page.MustWaitLoad()

    slider := page.MustElement("your_slider_css_selector")
    box := slider.MustShape().Box()

    track := generateTrack(sliderPosition)
    ctx := context.Background()
    page.Mouse.MustMove(box.X+box.Width/2, box.Y+box.Height/2, 1)
    page.Mouse.MustDown(input.Left)

    for _, move := range track {
        page.Mouse.MustMove(box.X+box.Width/2+float64(move), box.Y+box.Height/2, 1)
        time.Sleep(time.Duration(rand.Intn(20)+10) * time.Millisecond)
    }

    page.Mouse.MustUp(input.Left)
    page.MustScreenshot("result.png")
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值