用F#实现极验滑动验证码识别


本文将展示如何使用F#语言实现极验滑动验证码的自动识别。从模拟点击到识别滑动缺口、计算位移并模拟拖动滑块。如果认证失败,则重复调用直到成功。

识别思路
模拟点击切换为滑动验证,并显示验证界面。
识别滑动缺口的位置,计算位移。更多内容联系1436423940
模拟拖动滑块。
若认证失败,重复调用。
详细过程及代码
初始化
首先,初始化Selenium WebDriver对象并配置参数。极验验证码测试页面的网址如下:

fsharp

open System
open OpenQA.Selenium
open OpenQA.Selenium.Chrome
open System.Drawing
open System.Drawing.Imaging
open System.IO

type CrackGeetest() =
    let mutable driver = new ChromeDriver()
    let url = "https://www.geetest.com/type/"

    member this.Open() =
        driver.Navigate().GoToUrl(url)

    member this.Close() =
        driver.Quit()

    member this.WaitForElement(selector: By) =
        let wait = OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(10.0))
        wait.Until(fun d -> d.FindElement(selector))

    member this.ChangeToSlide() =
        let huadong = this.WaitForElement(By.CssSelector(".products-content ul > li:nth-child(2)"))
        huadong.Click()

    member this.GetGeetestButton() =
        let button = this.WaitForElement(By.CssSelector(".geetest_radar_tip"))
        button.Click()

    member this.WaitPic() =
        this.WaitForElement(By.CssSelector(".geetest_popup_wrap"))

    member this.GetSlider() =
        this.WaitForElement(By.ClassName("geetest_slider_button"))

    member this.GetScreenshot() =
        let screenshot = driver.GetScreenshot()
        screenshot.AsByteArray

    member this.GetGeetestImage(name: string) =
        let screenshotBytes = this.GetScreenshot()
        use ms = new MemoryStream(screenshotBytes)
        use bitmap = new Bitmap(ms)
        let element = this.WaitForElement(By.ClassName("geetest_canvas_img"))
        let location = element.Location
        let size = element.Size
        let rect = Rectangle(location.X, location.Y, size.Width, size.Height)
        let captcha = bitmap.Clone(rect, bitmap.PixelFormat)
        captcha.Save(name, ImageFormat.Png)
        captcha

    member this.DeleteStyle() =
        driver.ExecuteScript("document.querySelectorAll('canvas')[2].style=''") |> ignore

    member this.IsPixelEqual(img1: Bitmap, img2: Bitmap, x: int, y: int) =
        let c1 = img1.GetPixel(x, y)
        let c2 = img2.GetPixel(x, y)
        let threshold = 60
        Math.Abs(c1.R - c2.R) < threshold && Math.Abs(c1.G - c2.G) < threshold && Math.Abs(c1.B - c2.B) < threshold

    member this.GetGap(img1: Bitmap, img2: Bitmap) =
        let mutable left = 60
        for i in left .. img1.Width - 1 do
            for j in 0 .. img1.Height - 1 do
                if not (this.IsPixelEqual(img1, img2, i, j)) then
                    left <- i
                    return left
        left

    member this.GetTrack(distance: int) =
        let mutable track = []
        let mutable current = 0
        let mid = distance * 3 / 5
        let t = 0.2
        let mutable v = 0.0
        let distance = distance + 14
        while current < distance do
            let a = if current < mid then 2.0 else -1.5
            let v0 = v
            v <- v0 + a * t
            let move = v0 * t + 0.5 * a * t * t |> round |> int
            current <- current + move
            track <- move :: track
        List.rev track

    member this.MoveToGap(slider: IWebElement, tracks: int list) =
        let actions = new OpenQA.Selenium.Interactions.Actions(driver)
        actions.ClickAndHold(slider).Perform() |> ignore
        for x in tracks do
            actions.MoveByOffset(x, 0).Perform() |> ignore
        actions.Release().Perform() |> ignore

    member this.Crack() =
        try
            this.Open()
            this.ChangeToSlide()
            this.GetGeetestButton()
            this.WaitPic()
            let slider = this.GetSlider()
            let image1 = this.GetGeetestImage("captcha1.png")
            this.DeleteStyle()
            let image2 = this.GetGeetestImage("captcha2.png")
            let gap = this.GetGap(image1, image2)
            printfn "缺口位置: %d" gap
            let gap = gap - 6
            let track = this.GetTrack(gap)
            this.MoveToGap(slider, track)
            printfn "验证成功"
            System.Threading.Thread.Sleep(5000)
            this.Close()
        with
        | _ ->
            printfn "Failed-Retry"
            this.Crack()

[<EntryPoint>]
let main argv =
    let crackGeetest = new CrackGeetest()
    crackGeetest.Crack()
    0

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值