本文将展示如何使用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