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


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

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

fsharp

open OpenQA.Selenium
open OpenQA.Selenium.Chrome
open OpenQA.Selenium.Support.UI
open System.Drawing
open System.IO
open System.Threading

let border = 6

type CrackGeetest() =
    let url = "https://www.geetest.com/type/"
    let browser = new ChromeDriver()
    let wait = new WebDriverWait(browser, System.TimeSpan.FromSeconds(10.0))

    member _.Open() =
        browser.Navigate().GoToUrl(url)

    member _.Close() =
        browser.Quit()

    member _.ChangeToSlide() =
        wait.Until(fun driver -> driver.FindElement(By.CssSelector(".products-content ul > li:nth-child(2)"))).Click()

    member _.GetGeetestButton() =
        wait.Until(fun driver -> driver.FindElement(By.CssSelector(".geetest_radar_tip"))).Click()

    member _.WaitPic() =
        wait.Until(fun driver -> driver.FindElement(By.CssSelector(".geetest_popup_wrap")))

    member _.GetSlider() =
        wait.Until(fun driver -> driver.FindElement(By.ClassName("geetest_slider_button")))

    member _.GetScreenshot() =
        let screenshot = browser.GetScreenshot()
        let imageBytes = screenshot.AsByteArray
        Image.FromStream(new MemoryStream(imageBytes))

    member _.GetPosition() =
        let img = wait.Until(fun driver -> driver.FindElement(By.ClassName("geetest_canvas_img")))
        Thread.Sleep(2000)
        let location = img.Location
        let size = img.Size
        (location.Y, location.Y + size.Height, location.X, location.X + size.Width)

    member _.GetGeetestImage(name: string) =
        let (top, bottom, left, right) = _.GetPosition()
        printfn "验证码位置: %d, %d, %d, %d" top bottom left right
        let screenshot = _.GetScreenshot()
        let cropRect = Rectangle(left, top, right - left, bottom - top)
        let target = new Bitmap(cropRect.Width, cropRect.Height)
        use g = Graphics.FromImage(target)
        g.DrawImage(screenshot, Rectangle(0, 0, target.Width, target.Height), cropRect, GraphicsUnit.Pixel)
        target.Save(name)
        target

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

    member _.IsPixelEqual(img1: Image, img2: Image, x: int, y: int) =
        let bmp1 = img1 :?> Bitmap
        let bmp2 = img2 :?> Bitmap
        let c1 = bmp1.GetPixel(x, y)
        let c2 = bmp2.GetPixel(x, y)
        let threshold = 60
        abs (c1.R - c2.R) < threshold && abs (c1.G - c2.G) < threshold && abs (c1.B - c2.B) < threshold

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

    member _.GetTrack(distance: int) =
        let mutable current = 0
        let mid = distance * 3 / 5
        let t = 0.2
        let mutable v = 0.0
        let mutable track = []
        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 |> int
            current <- current + move
            track <- move :: track
        List.rev track

    member _.ShakeMouse() =
        let actions = new OpenQA.Selenium.Interactions.Actions(browser)
        actions.MoveByOffset(-3, 0).Perform()
        actions.MoveByOffset(2, 0).Perform()

    member _.MoveToGap(slider: IWebElement, tracks: int list) =
        let actions = new OpenQA.Selenium.Interactions.Actions(browser)
        actions.ClickAndHold(slider).Perform()
        for x in tracks do
            actions.MoveByOffset(x, 0).Perform()
        actions.Release().Perform()
        _.ShakeMouse()
        Thread.Sleep(500)

    member _.Crack() =
        try
            _.Open()
            _.ChangeToSlide()
            _.GetGeetestButton()
            _.WaitPic()
            let slider = _.GetSlider()
            let image1 = _.GetGeetestImage("captcha1.png")
            _.DeleteStyle()
            let image2 = _.GetGeetestImage("captcha2.png")
            let gap = _.GetGap(image1, image2) - border
            let track = _.GetTrack(gap)
            _.MoveToGap(slider, track)
            wait.Until(fun driver -> driver.FindElement(By.ClassName("geetest_success_radar_tip_content")).Text.Contains("验证成功")) |> ignore
            printfn "验证成功"
            Thread.Sleep(5000)
            _.Close()
        with
        | ex ->
            printfn "Failed-Retry: %s" ex.Message
            _.Crack()

[<EntryPoint>]
let main argv =
    let crack = CrackGeetest()
    crack.Crack()
    0
详细实现
在这篇文章中,我们使用F#实现了极验滑动验证码的识别。代码中使用了Selenium库来操作浏览器,通过模拟点击、获取验证码图片、计算滑动距离,并最终完成滑块拖动验证。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值