目标效果
本文将展示如何使用Haskell编程语言实现极验滑动验证码的自动识别。我们将详细解释每一步骤,从初始化浏览器到识别滑块并进行模拟拖动操作。
实现思路
模拟点击切换为滑动验证,并显示验证界面。
识别滑动缺口的位置,计算滑动距离。
模拟拖动滑块。
如果认证失败,则重复调用直到成功。更多内容联系1436423940
详细实现及代码
初始化
首先,初始化Selenium WebDriver对象并配置参数。极验验证码测试页面的网址如下:
haskell
{-# LANGUAGE OverloadedStrings #-}
import Control.Monad (void)
import Data.ByteString.Lazy (ByteString)
import Data.Text (Text)
import qualified Data.Text as T
import Data.Time (getCurrentTime, addUTCTime)
import Network.HTTP.Client (defaultManagerSettings, newManager)
import Selenium
import Selenium.WebDriver
import System.IO (hClose, hPutStrLn, openFile, IOMode(..))
import Control.Concurrent (threadDelay)
data CrackGeetest = CrackGeetest {
driver :: WebDriver
}
main :: IO ()
main = do
manager <- newManager defaultManagerSettings
driver <- startSession defaultCapabilities { browser = chrome }
let crack = CrackGeetest { driver = driver }
crackGeetest crack
crackGeetest :: CrackGeetest -> IO ()
crackGeetest crack = do
openPage crack
void $ changeToSlide crack
void $ getGeetestButton crack
waitPic crack
slider <- getSlider crack
image1 <- getGeetestImage crack "captcha1.png"
deleteStyle crack
image2 <- getGeetestImage crack "captcha2.png"
gap <- getGap image1 image2
let track = getTrack gap
moveToGap crack slider track
success <- waitUntil crack
if success then putStrLn "验证成功" else do
putStrLn "Failed-Retry"
crackGeetest crack
closePage crack
openPage :: CrackGeetest -> IO ()
openPage crack = void $ runWD (driver crack) $ openPage "https://www.geetest.com/type/"
closePage :: CrackGeetest -> IO ()
closePage crack = runWD (driver crack) $ closeSession
changeToSlide :: CrackGeetest -> IO Element
changeToSlide crack = runWD (driver crack) $ findElem (ByCSS ".products-content ul > li:nth-child(2)")
getGeetestButton :: CrackGeetest -> IO Element
getGeetestButton crack = runWD (driver crack) $ findElem (ByCSS ".geetest_radar_tip")
waitPic :: CrackGeetest -> IO ()
waitPic crack = runWD (driver crack) $ void $ findElem (ByCSS ".geetest_popup_wrap")
getSlider :: CrackGeetest -> IO Element
getSlider crack = runWD (driver crack) $ findElem (ByCSS ".geetest_slider_button")
getGeetestImage :: CrackGeetest -> FilePath -> IO ByteString
getGeetestImage crack filePath = do
screenshot <- runWD (driver crack) $ screenshotPage
saveImage screenshot filePath
return screenshot
saveImage :: ByteString -> FilePath -> IO ()
saveImage imgData path = do
handle <- openFile path WriteMode
hPutStrLn handle (T.unpack $ T.decodeUtf8 imgData)
hClose handle
deleteStyle :: CrackGeetest -> IO ()
deleteStyle crack = runWD (driver crack) $ executeScript [] "document.querySelectorAll('canvas')[2].style=''"
getGap :: ByteString -> ByteString -> IO Int
getGap img1 img2 = do
-- Implement image comparison logic here
return 60 -- Placeholder value for gap
getTrack :: Int -> [Int]
getTrack distance = [0..distance] -- Placeholder track
moveToGap :: CrackGeetest -> Element -> [Int] -> IO ()
moveToGap crack slider track = runWD (driver crack) $ do
click slider
forM_ track $ \offset -> moveTo (MoveBy offset 0)
release slider
waitUntil :: CrackGeetest -> IO Bool
waitUntil crack = runWD (driver crack) $ do
let endTime = addUTCTime 5 <$> getCurrentTime
checkSuccess endTime
where
checkSuccess endTime = do
now <- getCurrentTime
if now > endTime then return False else do
elem <- findElem (ByCSS ".geetest_success_radar_tip_content")
text <- getText elem
if text == "验证成功" then return True else checkSuccess endTime