在本文中,我们将展示如何使用Racket编程语言结合Selenium WebDriver来破解极验滑动验证码。通过模拟点击、识别滑动缺口、计算位移及模拟拖动滑块等步骤,我们能够实现自动化验证码破解。
识别流程
打开网页并切换到滑动验证模式。
识别滑动缺口的位置并计算位移。
模拟拖动滑块。
若认证失败,重复上述步骤。
实现步骤与代码
初始化
首先,初始化Selenium WebDriver对象并配置参数。极验验证码测试页面的网址如下:
racket
#lang racket
(require net/http-easy
(prefix-in selenium: "selenium/client.rkt") 更多内容联系1436423940
"selenium/core.rkt"
racket/format
racket/system)
(define URL "https://www.geetest.com/type/")
(define BORDER 6)
(define (initialize)
(selenium:start-driver "chrome"))
(define (open browser)
(selenium:get browser URL))
(define (close browser)
(selenium:quit browser))
(define (change-to-slide browser)
(selenium:click browser (selenium:find-element browser 'css ".products-content ul > li:nth-child(2)")))
(define (get-geetest-button browser)
(selenium:click browser (selenium:find-element browser 'css ".geetest_radar_tip")))
(define (wait-pic browser)
(selenium:wait-for browser 10 (selenium:presence-of-element-located 'css ".geetest_popup_wrap")))
(define (get-screenshot browser)
(selenium:get-screenshot browser))
(define (get-position browser)
(let* ((element (selenium:find-element browser 'class "geetest_canvas_img"))
(location (selenium:location element))
(size (selenium:size element)))
(list (hash-ref location 'y)
(+ (hash-ref location 'y) (hash-ref size 'height))
(hash-ref location 'x)
(+ (hash-ref location 'x) (hash-ref size 'width)))))
(define (get-slider browser)
(selenium:find-element browser 'class "geetest_slider_button"))
(define (save-image screenshot file-name)
(with-output-to-file file-name #:exists 'replace
(lambda () (write-bytes screenshot))))
(define (get-geetest-image browser file-name)
(let* ((position (get-position browser))
(screenshot (get-screenshot browser)))
(save-image screenshot file-name)
file-name))
(define (delete-style browser)
(selenium:execute-script browser "document.querySelectorAll('canvas')[2].style=''"))
(define (is-pixel-equal img1 img2 x y)
(define threshold 60)
(define (pixel img x y) (list-ref (car (image->list img)) (+ (* y (image-width img)) x)))
(let* ((pix1 (pixel img1 x y))
(pix2 (pixel img2 x y)))
(and (< (abs (- (red pix1) (red pix2))) threshold)
(< (abs (- (green pix1) (green pix2))) threshold)
(< (abs (- (blue pix1) (blue pix2))) threshold))))
(define (get-gap img1 img2)
(define left 60)
(for*/first ((i (in-range left (image-width img1)))
(j (in-range (image-height img1))))
(unless (is-pixel-equal img1 img2 i j)
i)))
(define (get-track distance)
(define (helper dist mid)
(if (< dist mid)
(append (list (random 5)) (helper (+ dist (random 5)) mid))
(list dist)))
(helper 0 (* distance 3/5)))
(define (move-to-gap browser slider tracks)
(selenium:click-and-hold browser slider)
(for ([x tracks])
(selenium:move-by-offset browser x 0))
(selenium:release browser slider))
(define (wait-for-success browser)
(selenium:wait-for browser 10 (selenium:text-to-be-present-in-element 'class "geetest_success_radar_tip_content" "验证成功")))
(define (crack)
(let ((browser (initialize)))
(open browser)
(change-to-slide browser)
(get-geetest-button browser)
(wait-pic browser)
(let* ((slider (get-slider browser))
(image1 (get-geetest-image browser "captcha1.png"))
(delete-style browser)
(image2 (get-geetest-image browser "captcha2.png"))
(gap (- (get-gap image1 image2) BORDER))
(track (get-track gap)))
(move-to-gap browser slider track)
(if (wait-for-success browser)
(printf "验证成功\n")
(begin
(printf "验证失败,重试中...\n")
(crack))))
(close browser)))
(crack)