爬虫之滑动验证码破解

具体代码如下:

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 #pip3 install pillow
import time
def get_snap(driver):
    '''
    获取整个屏幕截图
    :param driver:
    :return:
    '''
    driver.save_screenshot('snap.png')
    full_snap_obj = Image.open('snap.png')
    return full_snap_obj
def get_code(driver):
    '''
    从整个屏幕截图中获取验证码图片
    :param driver:
    :return:
    '''
    img = driver.find_element_by_class_name('geetest_canvas_img')
    time.sleep(2)  # 保证图片已经加载完毕

    location = img.location
    size = img.size

    left = location['x']
    top = location['y']
    right = left + size['width']
    bottom = top + size['height']

    # 从整张图片中截图验证码图片
    full_snap_obj = get_snap(driver)
    image = full_snap_obj.crop((left, top, right, bottom))
    # image.show()
    return image
def get_distance(image1,image2):
    '''
    获取图片应该滑动的距离
    :param image1:
    :param image2:
    :return:
    '''
    start=57
    threhold=60
    # print(image1.size)
    # print(image2.size)

    for x in range(start,image1.size[0]):
        for y in range(image1.size[1]):
            rgb1=image1.load()[x,y]
            rgb2=image2.load()[x,y]
            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 x-7
    return x-7

def get_tracks(distance):
    '''
    模拟真人滑动的轨迹,获得模拟轨迹
    :param distance: 
    :return: 
    '''
    distance+=20
    v0=0
    t=0.2
    mid=distance*3/5
    current=0
    forward_tracks=[]

    while current < distance:
        if current < mid:
            a=2
        else:
            a=-3

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

    back_tracks=[-3,-3,-2,-2,-2,-2,-2,-1,-1,-1,-1]
    return {'forward_tracks':forward_tracks,'back_tracks':back_tracks}


def main():
    driver=webdriver.Chrome()
    driver.implicitly_wait(3)
    try:
        driver.get("https://passport.cnblogs.com/user/signin")
        #1、输入用户名和密码,并提交
        user_input=driver.find_element_by_id("input1")
        pswd_input=driver.find_element_by_id("input2")
        submit_input=driver.find_element_by_id("signin")
        user_input.send_keys("931880645")
        pswd_input.send_keys("zhangli53373306@")
        submit_input.click()

        #2、点击获取没有缺口的验证码图片
        time.sleep(1)
        show_code=driver.find_element_by_class_name("geetest_radar_tip")
        show_code.click()

        #3、截取没有缺口的验证码的图片
        img1=get_code(driver)

        #4、点击滑动按钮,获取有缺口的验证码图片
        slider_button=driver.find_element_by_class_name("geetest_slider_button")
        slider_button.click()

        #5、截取有缺口的验证码的图片
        img2=get_code(driver)

        # 6、对比两张图片的RGB,得到位移
        distance=get_distance(img1,img2)

        # 7、模仿人的行为习惯,拿到移动轨迹
        tracks=get_tracks(distance)
        # 8、按照位移滑动,通过认证
        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 track in tracks['back_tracks']:
            ActionChains(driver).move_by_offset(xoffset=track, yoffset=0).perform()

        time.sleep(0.5)
        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(50)

    finally:
        driver.close()

if __name__ == '__main__':
    main()

 

posted @ 2018-01-11 21:38  骑猪走秀  阅读(36)  评论(0)    收藏  举报