驗證碼破解-最新滑動驗證碼

一、簡單說明

     驗證碼中極驗驗證碼是做的非常好的一種驗證方式,在第三代點選漢字未出現之前,滑動驗證碼很是流行。現在依然有很多網站在使用。不知什麼時候極驗似乎對滑動驗證碼做了小小的改進。之前需要驗證時會先出現這種不帶滑塊和陰影的驗證碼。

拖動或者點擊按鈕之後,纔會出現滑塊和陰影,這樣僅需要比較兩張圖形之間差異,就可以計算出需要滑動的距離。但是,

現在開始驗證時就會出現第二種驗證圖形,沒有背景圖片作參考,怎麼計算需要滑動的距離呢?

二、解析過程

     博主檢查頁面源碼時懷疑滑塊和陰影是css樣式造成的。於是,頁面更改css樣式看是否能顯示背景圖片。當博主將

更改爲

時,驗證碼真的只剩下背景圖片了,點擊按鈕之後,就可以進行滑塊認證。這樣我們只需要通過js操作css樣式屬性,之後的破解過程就和以前的模式無多大區別了。

三、項目代碼

from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from PIL import Image
import time


def get_image(driver, n):
    canvas = driver.find_element_by_xpath('/html/body/div[3]/div[2]/div[2]/div[1]/div[1]/div/a/div[1]/canvas')
    left = canvas.location['x']
    top = canvas.location['y']
    elementWidth = canvas.location['x'] + canvas.size['width']
    elementHeight = canvas.location['y'] + canvas.size['height']
    driver.save_screenshot(n + '.png')
    picture = Image.open(n + '.png')
    picture = picture.crop((left, top, elementWidth, elementHeight))
    picture.save('photo' + n + '.png')
    return picture


def get_space(picture1, picture2):
    start = 57
    threhold = 60

    for i in range(start, picture1.size[0]):
        for j in range(picture1.size[1]):
            rgb1 = picture1.load()[i, j]
            rgb2 = picture2.load()[i, j]
            res1 = abs(rgb1[0] - rgb2[0])
            res2 = abs(rgb1[1] - rgb2[1])
            res3 = abs(rgb1[2] - rgb2[2])
            if not (res1 < threhold and res2 < threhold and res3 < threhold):
                return i
    return i - 7


def get_tracks(space):
    space += 20  # 先滑過一點,最後再反着滑動回來
    v = 0
    t = 0.2
    forward_tracks = []

    current = 0
    mid = space * 3 / 5
    while current < space:
        if current < mid:
            a = 2
        else:
            a = -3

        s = v * t + 0.5 * a * (t ** 2)
        v = v + a * t
        current += s
        forward_tracks.append(round(s))

    # 反着滑動到準確位置
    back_tracks = [-3, -3, -2, -2, -2, -2, -2, -1, -1, -1]  # 總共等於-20

    return {'forward_tracks': forward_tracks, 'back_tracks': back_tracks}


def main():
    driver = webdriver.Chrome()
    driver.get('http://www.geetest.com/type/')
    time.sleep(1)
    driver.find_element_by_xpath('//*[@id="app"]/section/div/ul/li[2]/h2').click()
    time.sleep(1)
    # 1、出現滑塊驗證,獲取有缺口的圖片
    driver.find_element_by_xpath('//*[@id="captcha"]/div[2]/div[2]/div[1]/div[3]/span[1]').click()
    time.sleep(1)
    picture1 = get_image(driver, '1')
    # 2、執行js改變css樣式,顯示背景圖
    driver.execute_script('document.querySelectorAll("canvas")[2].style=""')
    time.sleep(1)
    # 3、獲取沒有缺口的圖片
    picture2 = get_image(driver, '2')
    # 4、對比兩種圖片的像素點,找出位移
    space =get_space(picture1, picture2)
    tracks = get_tracks(space)
    button = driver.find_element_by_class_name('geetest_slider_button')
    ActionChains(driver).click_and_hold(button).perform()
    for track in tracks['forward_tracks']:
        ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform()
    time.sleep(0.5)
    for back_track in tracks['back_tracks']:
        ActionChains(driver).move_by_offset(xoffset=back_track, yoffset=0).perform()
    ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform()
    ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform()
    time.sleep(0.5)
    ActionChains(driver).release().perform()
    driver.close()
    driver.quit()

if __name__ == '__main__':
    main()

細節方面還沒來得及調整,待續。。。。。

 

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