溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python3中識別極驗滑動驗證碼的方法

發(fā)布時間:2020-08-05 15:06:12 來源:億速云 閱讀:383 作者:小新 欄目:編程語言

這篇文章將為大家詳細講解有關Python3中識別極驗滑動驗證碼的方法,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

上節(jié)我們了解了圖形驗證碼的識別,簡單的圖形驗證碼我們可以直接利用 Tesserocr 來識別,但是近幾年又出現(xiàn)了一些新型驗證碼,如滑動驗證碼,比較有代表性的就是極驗驗證碼,它需要拖動拼合滑塊才可以完成驗證,相對圖形驗證碼來說識別難度上升了幾個等級,本節(jié)來講解下極驗驗證碼的識別過程。

1. 本節(jié)目標

本節(jié)我們的目標是用程序來識別并通過極驗驗證碼的驗證,其步驟有分析識別思路、識別缺口位置、生成滑塊拖動路徑,最后模擬實現(xiàn)滑塊拼合通過驗證。

2. 準備工作

本次我們使用的 Python 庫是 Selenium,使用的瀏覽器為 Chrome,在此之前請確保已經(jīng)正確安裝好了 Selenium 庫、Chrome瀏覽器并配置好了 ChromeDriver,相關流程可以參考第一章的說明。

3. 了解極驗驗證碼

極驗驗證碼其官網(wǎng)為:http://www.geetest.com/,它是一個專注于提供驗證安全的系統(tǒng),主要驗證方式是拖動滑塊拼合圖像,若圖像完全拼合,則驗證成功,即可以成功提交表單,否則需要重新驗證,樣例如圖8-5 和 8-6 所示:

Python3中識別極驗滑動驗證碼的方法

                                                   圖 8-5 驗證碼示例

Python3中識別極驗滑動驗證碼的方法

                                                     圖 8-6 驗證碼示例

現(xiàn)在極驗驗證碼已經(jīng)更新到了 3.0 版本,截至 2017 年 7 月全球已有十六萬家企業(yè)正在使用極驗,每天服務響應超過四億次,廣泛應用于直播視頻、金融服務、電子商務、游戲娛樂、政府企業(yè)等各大類型網(wǎng)站,下面是斗魚、魅族的登錄頁面,可以看到其都對接了極驗驗證碼,如圖 8-7 和 8-8 所示:

Python3中識別極驗滑動驗證碼的方法

                                                        圖 8-7 斗魚登錄頁面

Python3中識別極驗滑動驗證碼的方法

                                                                                     圖 8-8 魅族登錄頁面

4. 極驗驗證碼的特點

這種驗證碼相較于圖形驗證碼來說識別難度更大,極驗驗證碼首先需要在前臺驗證通過,對于極驗 3.0,我們首先需要點擊按鈕進行智能驗證,如果驗證不通過,則會彈出滑動驗證的窗口,隨后需要拖動滑塊拼合圖像進行驗證,驗證之后會生成三個加密參數(shù),參數(shù)隨后通過表單提交到后臺,后臺還會進行一次驗證。

另外極驗還增加了機器學習的方法來識別拖動軌跡,官方網(wǎng)站的安全防護說明如下:

·三角防護之防模擬

惡意程序模仿人類行為軌跡對驗證碼進行識別。針對模擬,極驗擁有超過 4000 萬人機行為樣本的海量數(shù)據(jù)。利用機器學習和神經(jīng)網(wǎng)絡構建線上線下的多重靜態(tài)、動態(tài)防御模型。識別模擬軌跡,界定人機邊界。

·三角防護之防偽造

惡意程序通過偽造設備瀏覽器環(huán)境對驗證碼進行識別。針對偽造,極驗利用設備基因技術。深度分析瀏覽器的實際性能來辨識偽造信息。同時根據(jù)偽造事件不斷更新黑名單,大幅提高防偽造能力。

·三角防護之防暴力

惡意程序短時間內(nèi)進行密集的攻擊,對驗證碼進行暴力識別

針對暴力,極驗擁有多種驗證形態(tài),每一種驗證形態(tài)都有利用神經(jīng)網(wǎng)絡生成的海量圖庫儲備,每一張圖片都是獨一無二的,且圖庫不斷更新,極大程度提高了暴力識別的成本。

另外極驗的驗證相對于普通驗證方式更加方便,體驗更加友好,其官方網(wǎng)站說明如下:

·點擊一下,驗證只需要 0.4 秒

極驗始終專注于去驗證化實踐,讓驗證環(huán)節(jié)不再打斷產(chǎn)品本身的交互流程,最終達到優(yōu)化用戶體驗和提高用戶轉(zhuǎn)化率的效果。

·全平臺兼容,適用各種交互場景

極驗兼容所有主流瀏覽器甚至古老的IE6,也可以輕松應用在iOS和Android移動端平臺,滿足各種業(yè)務需求,保護網(wǎng)站資源不被濫用和盜取。

·面向未來,懂科技,更懂人性

極驗在保障安全同時不斷致力于提升用戶體驗,精雕細琢的驗證面板,流暢順滑的驗證動畫效果,讓驗證過程不再枯燥乏味。

因此,相較于一般驗證碼,極驗的驗證安全性和易用性有了非常大的提高。

5. 識別思路

但是對于應用了極驗驗證碼的網(wǎng)站,識別并不是沒有辦法的。如果我們直接模擬表單提交的話,加密參數(shù)的構造是個問題,參數(shù)構造有問題服務端就會校驗失敗,所以在這里我們采用直接模擬瀏覽器動作的方式來完成驗證,在 Python 中我們就可以使用 Selenium 來通過完全模擬人的行為的方式來完成驗證,此驗證成本相對于直接去識別加密算法容易不少。

首先我們找到一個帶有極驗驗證的網(wǎng)站,最合適的當然為極驗官方后臺了,鏈接為:https://account.geetest.com/login,首先可以看到在登錄按鈕上方有一個極驗驗證按鈕,如圖 8-9 所示:

Python3中識別極驗滑動驗證碼的方法

                                                           圖 8-9 驗證按鈕

此按鈕為智能驗證按鈕,點擊一下即可智能驗證,一般來說如果是同一個 Session,一小段時間內(nèi)第二次登錄便會直接通過驗證,如果智能識別不通過,則會彈出滑動驗證窗口,我們便需要拖動滑塊來拼合圖像完成二步驗證,如圖 8-10 所示:

Python3中識別極驗滑動驗證碼的方法

                                                                                  圖 8-10 拖動示例

驗證成功后驗證按鈕便會變成如下狀態(tài),如圖 8-11 所示:

Python3中識別極驗滑動驗證碼的方法

                                                                                    圖 8-11 驗證成功結果

接下來我們便可以進行表單提交了。

所以在這里我們要識別驗證需要做的有三步:

·模擬點擊驗證按鈕

·識別滑動缺口的位置

·模擬拖動滑塊

第一步操作是最簡單的,我們可以直接用 Selenium 模擬點擊按鈕即可。

第二步操作識別缺口的位置比較關鍵,需要用到圖像的相關處理方法,那缺口怎么找呢?首先來觀察一下缺口的樣子,如圖 8-12 和 8-13 所示:

Python3中識別極驗滑動驗證碼的方法

                                                       圖 8-12 缺口示例

Python3中識別極驗滑動驗證碼的方法

                                                        圖 8-13 缺口示例

可以看到缺口的四周邊緣有明顯的斷裂邊緣,而且邊緣和邊緣周圍有明顯的區(qū)別,我們可以實現(xiàn)一個邊緣檢測算法來找出缺口的位置。對于極驗來說,我們可以利用和原圖對比檢測的方式來識別缺口的位置,因為在沒有滑動滑塊之前,缺口其實是沒有呈現(xiàn)的,如圖 8-14 所示:

Python3中識別極驗滑動驗證碼的方法

                                                          圖 8-14 初始狀態(tài)

所以我們可以同時獲取兩張圖片,設定一個對比閾值,然后遍歷兩張圖片找出相同位置像素 RGB 差距超過此閾值的像素點位置,那么此位置就是缺口的位置。

第三步操作看似簡單,但是其中的坑比較多,極驗驗證碼增加了機器軌跡識別,勻速移動、隨機速度移動等方法都是不行的,只有完全模擬人的移動軌跡才可以通過驗證,而人的移動軌跡一般是先加速后減速的,這又涉及到物理學中加速度的相關問題,我們需要模擬這個過程才能成功。

有了基本的思路之后就讓我們用程序來實現(xiàn)一下它的識別過程吧。

6. 初始化

首先這次我們選定的鏈接為:https://account.geetest.com/login,也就是極驗的管理后臺登錄頁面,在這里我們首先初始化一些配置,如 Selenium 對象的初始化及一些參數(shù)的配置:

EMAIL = 'test@test.com'
PASSWORD = '123456'
class CrackGeetest():
    def __init__(self):
        self.url = 'https://account.geetest.com/login'
        self.browser = webdriver.Chrome()
        self.wait = WebDriverWait(self.browser, 20)
        self.email = EMAIL
        self.password = PASSWORD

其中 EMAIL 和 PASSWORD 就是登錄極驗需要的用戶名和密碼,如果沒有的話可以先注冊一下。

7. 模擬點擊

隨后我們需要實現(xiàn)第一步的操作,也就是模擬點擊初始的驗證按鈕,所以我們定義一個方法來獲取這個按鈕,利用顯式等待的方法來實現(xiàn):

def get_geetest_button(self):
    """
    獲取初始驗證按鈕
    :return: 按鈕對象
    """
    button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_radar_tip')))
    return button

獲取之后就會獲取一個 WebElement 對象,調(diào)用它的 click() 方法即可模擬點擊,代碼如下:

# 點擊驗證按鈕
button = self.get_geetest_button()
button.click()

到這里我們第一步的工作就完成了。

8. 識別缺口

接下來我們需要識別缺口的位置,首先我們需要將前后的兩張比對圖片獲取下來,然后比對二者的不一致的地方即為缺口。首先我們需要獲取不帶缺口的圖片,利用 Selenium 選取圖片元素,然后得到其所在位置和寬高,隨后獲取整個網(wǎng)頁的截圖,再從截圖中裁切出來即可,代碼實現(xiàn)如下:

def get_position(self):
    """
    獲取驗證碼位置
    :return: 驗證碼位置元組
    """
    img = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'geetest_canvas_img')))
    time.sleep(2)
    location = img.location
    size = img.size
    top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], 
    location['x'] + size[
        'width']
    return (top, bottom, left, right)
def get_geetest_image(self, name='captcha.png'):
    """
    獲取驗證碼圖片
    :return: 圖片對象
    """
    top, bottom, left, right = self.get_position()
    print('驗證碼位置', top, bottom, left, right)
    screenshot = self.get_screenshot()
    captcha = screenshot.crop((left, top, right, bottom))
    return captcha

在這里 get_position() 函數(shù)首先獲取了圖片對象,然后獲取了它的位置和寬高,隨后返回了其左上角和右下角的坐標。而 get_geetest_image() 方法則是獲取了網(wǎng)頁截圖,然后調(diào)用了 crop() 方法將圖片再裁切出來,返回的是 Image 對象。

隨后我們需要獲取第二張圖片,也就是帶缺口的圖片,要使得圖片出現(xiàn)缺口,我們只需要點擊一下下方的滑塊即可,觸發(fā)這個動作之后,圖片中的缺口就會顯現(xiàn),實現(xiàn)如下:

def get_slider(self):
    """
    獲取滑塊
    :return: 滑塊對象
    """
    slider = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'geetest_slider_button')))
    return slider

利用 get_slider() 方法獲取滑塊對象,接下來調(diào)用其 click() 方法即可觸發(fā)點擊,缺口圖片即可呈現(xiàn):

# 點按呼出缺口
slider = self.get_slider()
slider.click()

隨后還是調(diào)用 get_geetest_image() 方法將第二張圖片獲取下來即可。

到現(xiàn)在我們就已經(jīng)得到了兩張圖片對象了,分別賦值給變量 image1 和 image2,接下來對比圖片獲取缺口即可。要對比圖片的不同之處,我們在這里遍歷圖片的每個坐標點,獲取兩張圖片對應像素點的 RGB 數(shù)據(jù),然后判斷二者的 RGB 數(shù)據(jù)差異,如果差距超過在一定范圍內(nèi),那就代表兩個像素相同,繼續(xù)比對下一個像素點,如果差距超過一定范圍,則判斷像素點不同,當前位置即為缺口位置,代碼實現(xiàn)如下:

def is_pixel_equal(self, image1, image2, x, y):
    """
    判斷兩個像素是否相同
    :param image1: 圖片1
    :param image2: 圖片2
    :param x: 位置x
    :param y: 位置y
    :return: 像素是否相同
    """
    # 取兩個圖片的像素點
    pixel1 = image1.load()[x, y]
    pixel2 = image2.load()[x, y]
    threshold = 60
    if abs(pixel1[0] - pixel2[0]) < threshold and abs(pixel1[1] - pixel2[1]) < threshold and abs(
            pixel1[2] - pixel2[2]) < threshold:
        return True
    else:
        return False
def get_gap(self, image1, image2):
    """
    獲取缺口偏移量
    :param image1: 不帶缺口圖片
    :param image2: 帶缺口圖片
    :return:
    """
    left = 60
    for i in range(left, image1.size[0]):
        for j in range(image1.size[1]):
            if not self.is_pixel_equal(image1, image2, i, j):
                left = i
                return left
    return left

get_gap() 方法即為獲取缺口位置的方法,此方法的參數(shù)為兩張圖片,一張為帶缺口圖片,另一張為不帶缺口圖片,在這里遍歷兩張圖片的每個像素,然后利用 is_pixel_equal() 方法判斷兩張圖片同一位置的像素是否相同,比對的時候比較了兩張圖 RGB 的絕對值是否均小于定義的閾值 threshold,如果均在閾值之內(nèi),則像素點相同,繼續(xù)遍歷,否則遇到不相同的像素點就是缺口的位置。

在這里比如兩張對比圖片如下,如圖 8-15 和 8-16 所示:

Python3中識別極驗滑動驗證碼的方法

                 圖 8-15 初始狀態(tài)

Python3中識別極驗滑動驗證碼的方法

                                                         圖 8-16 后續(xù)狀態(tài)

兩張圖片其實有兩處明顯不同的地方,一個就是待拼合的滑塊,一個就是缺口,但是滑塊的位置會出現(xiàn)在左邊位置,缺口會出現(xiàn)在與滑塊同一水平線的位置,所以缺口一般會在滑塊的右側(cè),所以要尋找缺口的話,我們直接從滑塊右側(cè)尋找即可,所以在遍歷的時候我們直接設置了遍歷的起始橫坐標為 60,也就是在滑塊的右側(cè)開始識別,這樣識別出的結果就是缺口的位置了。

到現(xiàn)在為止,我們就可以獲取缺口的位置了,剩下最后一步模擬拖動就可以完成驗證了。

9. 模擬拖動

模擬拖動的這個過程說復雜并不復雜,只是其中的坑比較多?,F(xiàn)在我們已經(jīng)獲取到了缺口的位置,接下來只需要調(diào)用拖動的相關函數(shù)將滑塊拖動到對應位置不就好了嗎?然而事實很殘酷,如果勻速拖動,極驗必然會識別出來這是程序的操作,因為人是無法做到完全勻速拖動的,極驗利用機器學習模型篩選出此類數(shù)據(jù),歸類為機器操作,驗證碼識別失敗。

隨后我又嘗試了分段模擬,將拖動過程劃分幾段,每段設置一個平均速度,同時速度圍繞該平均速度小幅度隨機抖動,同樣無法完成驗證。

最后嘗試了完全模擬加速減速的過程通過了驗證,在前段滑塊需要做勻加速運動,后面需要做勻減速運動,在這里利用物理學的加速度公式即可完成。

設滑塊滑動的加速度用 a 來表示,當前速度用 v 表示,初速度用 v0 表示,位移用 x 表示,所需時間用 t 表示,則它們之間滿足如下關系:

x = v0 * t + 0.5 * a * t * t 
v = v0 + a * t

接下來我們利用兩個公式可以構造一個軌跡移動算法,計算出先加速后減速的運動軌跡,代碼實現(xiàn)如下:

def get_track(self, distance):
    """
    根據(jù)偏移量獲取移動軌跡
    :param distance: 偏移量
    :return: 移動軌跡
    """
    # 移動軌跡
    track = []
    # 當前位移
    current = 0
    # 減速閾值
    mid = distance * 4 / 5
    # 計算間隔
    t = 0.2
    # 初速度
    v = 0
    while current < distance:
        if current < mid:
            # 加速度為正2
            a = 2
        else:
            # 加速度為負3
            a = -3
        # 初速度v0
        v0 = v
        # 當前速度v = v0 + at
        v = v0 + a * t
        # 移動距離x = v0t + 1/2 * a * t^2
        move = v0 * t + 1 / 2 * a * t * t
        # 當前位移
        current += move
        # 加入軌跡
        track.append(round(move))
    return track

在這里我們定義了 get_track() 方法,傳入的參數(shù)為移動的總距離,返回的是運動軌跡,用 track 表示,它是一個列表,列表的每個元素代表每次移動多少距離。

首先定義了一個變量 mid,即減速的閾值,也就是加速到什么位置就開始減速,在這里定義為 4/5,即模擬前 4/5 路程是加速過程,后 1/5 是減速過程。

隨后定義了當前位移的距離變量 current,初始為 0,隨后進入 while 循環(huán),循環(huán)的條件是當前位移小于總距離。在循環(huán)里我們分段定義了加速度,其中加速過程加速度定義為2,減速過程加速度定義為 -3,隨后再套用位移公式計算出某個時間段內(nèi)的位移,同時將當前位移更新并記錄到軌跡里即可。

這樣直到運動軌跡達到總距離時即終止循環(huán),最后得到的 track 即記錄了每個時間間隔移動了多少位移,這樣滑塊的運動軌跡就得到了。

最后我們只需要按照該運動軌跡拖動滑塊即可,方法實現(xiàn)如下:

def move_to_gap(self, slider, tracks):
    """
    拖動滑塊到缺口處
    :param slider: 滑塊
    :param tracks: 軌跡
    :return:
    """
    ActionChains(self.browser).click_and_hold(slider).perform()
    for x in tracks:
        ActionChains(self.browser).move_by_offset(xoffset=x, yoffset=0).perform()
    time.sleep(0.5)
    ActionChains(self.browser).release().perform()

在這里傳入的參數(shù)為滑塊對象和運動軌跡,首先調(diào)用ActionChains 的 click_and_hold() 方法按住拖動底部滑塊,隨后遍歷運動軌跡獲取每小段位移距離,調(diào)用 move_by_offset() 方法移動此位移,最后移動完成之后調(diào)用 release() 方法松開鼠標即可。

這樣再經(jīng)過測試,驗證就通過了,識別完成,效果圖 8-17 所示:

Python3中識別極驗滑動驗證碼的方法

                                                 圖 8-17 識別成功結果

最后,我們只需要將表單完善,模擬點擊登錄按鈕即可完成登錄,成功登錄后即跳轉(zhuǎn)到后臺。

關于Python3中識別極驗滑動驗證碼的方法就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI