極驗驗證碼,通用破解

首先,我們來理一下思路:

極驗是專業提供第三方服務的,既然是第三方服務,就表明 驗證滑動是否成功的服務端是在極驗的後臺。

那麼用戶的流程就應該是:

1、訪問目標網頁,獲得表明商戶的參數  

                                ↓

2、帶着這個參數請求極驗,獲得滑動圖片

                                ↓

3、用戶拖動圖片,返回軌跡等數據給極驗

                                ↓

4、極驗返回驗證結果,如果成功則附帶一個驗證成功的參數

                                ↓

5、攜帶這個參數即可請求目標網頁後續內容

那其實我們就可以利用這個三方交互的流程,儘量讓我們的代碼可複用。

所以思路很清晰,我們的流程就應該是:

1、訪問目標網頁,獲得表明商戶的參數  

                                ↓

2、調用我們的服務,獲得一個驗證成功的參數

                                ↓

3、攜帶這個參數即可請求目標網頁後續內容

也就是說,我們的代碼是隻與極驗交互,傳入一個參數,返回一個參數即可。

我們先來看一下極驗的請求參數:

很明顯,兩個參數,gt 和 challenge 。

極驗的官方使用文檔裏面有說明:

果然,就跟我們的推測一樣,我們只需要請求目標網頁即可拿到這兩個參數。

而最終的驗證成功返回值:

這個validate就是我們需要的參數。

也就是:

gt, challenge = get_gt()  #和目標網站交互
validate = get_validate(gt, challenge)  #和極驗交互
result = get_result(validate)  #和目標網站交互

很明顯,我們可以複用的就是 get_validate,這也是破解的重點:

那首先我們需要一個滑動驗證碼的模板:

極驗文檔中直接有使用樣例:https://www.geetest.com/demo/slide-custom.html

但是他的傳入參數已經寫死,所以我們需要對這個html進行加工一下:

可以看到他取參數是直接調用ajax,參數放在data中:

而我們的需求是參數可以變化的,所以我們只需要稍作修改:

請求時只需用get請求傳入參數即可。

接下來就是常規的selenium模擬滑動的內容了,網上樣例很多,我就不多說了。

只需要注意一點就是url需要使用我們自己的html:

url = './jiyan.html?success=1&new_captcha=true&gt={}&challenge={}'.format(gt, challenge)

補充一點:

極驗的圖片是使用convas直接生成的,拼接比較繁瑣,我們使用selenium直接截圖比較方便:

其中image1, image2分別爲滑塊在最左端和最右端時的截圖,主要是用來確定y的位置,裁剪圖片,提高準確率。

二值化閾值通過y的位置範圍內的平均閾值來確定。

# 通過比較兩張圖片確定y位置
def get_y(image1, image2):
    y_s = []
    for i in range(image1.size[0] - 60, image1.size[0]):
        for j in range(image1.size[1]):

            rgb1 = image1.load()[i, j]
            rgb2 = image2.load()[i, j]
            if rgb1[1] == rgb2[1] and rgb1[2] == rgb2[2] and rgb1[3] == rgb2[3]:
                continue
            y_s.append(j)

    y_s_s = []
    for y in range(min(y_s), max(y_s)):
        if y_s.count(y) > 40:
            y_s_s.append(y)
    return max(y_s_s), min(y_s_s)


# 獲取圖片的平均灰度值
def get_ave_rgb(image1):
    rgb = []
    for i in range(image1.size[0]):
        for j in range(image1.size[1]):
            rgb.append(image1.load()[i, j])
    return np.mean(rgb)


def get_x(img_11, img_22):
    y1, y2 = get_y(img_11, img_22)
    cropImg = img_11.crop((0, y2, img_11.size[0], y1))
    image1 = cropImg.convert('L')

    threshold = int(get_ave_rgb(image1)) - 30  # 閾值通過平均灰度值確定

    # 二值化
    table = []
    for i in range(256):
        if i < threshold:
            table.append(0)
        else:
            table.append(1)
    img = image1.point(table, '1')
    img.save('tu3.png')

    node_list = []
    for x in range(40, img.size[0] - 80, 2):
        # (x0,y0,x1,y1)
        box1 = (x, 0, x + 43, img.size[1])

        image1 = img.crop(box1)
        # image1.show()
        matrix = np.asarray(image1)
        node_num = np.sum(matrix)
        node_list.append((x, node_num))

    return min(node_list, key=lambda x: x[1])

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章