1. 程式人生 > >較簡單的滑動驗證破解

較簡單的滑動驗證破解

from https://blog.csdn.net/chenxiao17301/article/details/82911155

 

一、新舊版對比

以前的滑動驗證碼可以得到原背景圖和有缺口的背景圖,兩圖比較,就可以計算出需要滑動的距離。

新版的驗證碼,沒有背景圖片作參考,一點開就是帶有缺口的圖片,那麼,我們怎麼計算需要滑動的距離呢?

二、解析過程

     在檢查頁面原始碼時懷疑滑塊和陰影是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]/div/canvas[2]')
        canvas = driver.find_element_by_xpath('//canvas[@class="geetest_canvas_slice geetest_absolute"]')
        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 = 60
        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 - 10
    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, -3, -4]
        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()  # 選擇滑動行為驗證
        # driver.find_element_by_xpath('//div[@class="geetest_slider_button"]').click()  ????why
        time.sleep(1)
        # 1、出現滑塊驗證,獲取有缺口的圖片
        # driver.find_element_by_xpath('//*[@id="captcha"]/div[2]/div[2]/div[1]/div[3]/span[1]').click()
        driver.find_element_by_xpath('//span[@class="geetest_wait_dot geetest_dot_2"]').click()
        time.sleep(1)
        picture1 = get_image(driver, '1')
        # 2、執行js改變css樣式,顯示背景圖!!!!!重點是這一步!
        # driver.execute_script('document.querySelectorAll("canvas")[1].style=""')  # 不是1
        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()
        time.sleep(3)
        # driver.close()
        # driver.quit()
    if __name__ == '__main__':
        main()