滑动验证

代码

from selenium import webdriver  # 用来驱动浏览器的
from selenium.webdriver import ActionChains  # 破解滑动验证码的时候用的 可以拖动图片
import time
from PIL import Image
import random

option = webdriver.ChromeOptions()
option.add_argument('disable-infobars')

driver = webdriver.Chrome(chrome_options=option)

def get_snap(driver):

    # selenium自带的截图网页全屏图片
    driver.save_screenshot('snap.png')

    img = driver.find_element_by_class_name('geetest_canvas_img')

    left = img.location['x']

    upper = img.location['y']

    right = left + img.size['width']
    lower = upper + img.size['height']

    # print(left, upper, right, lower)
    img_obj = Image.open('snap.png')

    # 对屏幕进行截取,获取滑动验证图片
    image = img_obj.crop((left, upper, right, lower))

    return image

def get_image1(driver):

    time.sleep(0.2)
    js_code = '''
    var x = document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display="block";
    console.log(x)
    '''

    time.sleep(1)
    driver.execute_script(js_code)


    # 截取图片
    img_obj = get_snap(driver)

    return img_obj


def get_image2(driver):
    time.sleep(0.2)

    js_code = '''
    var x = document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display="none";
    console.log(x)
    '''

    driver.execute_script(js_code)

    time.sleep(1)

    # 截取图片
    img_obj = get_snap(driver)

    return img_obj


def get_distance(image1, image2):

    # 初始值
    start = 60

    # 滑块色差
    color_num = 60

    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]

            r = abs(rgb1[0] - rgb2[0])
            g = abs(rgb1[1] - rgb2[1])
            b = abs(rgb1[2] - rgb2[2])

            if not (r < color_num and g < color_num and b < color_num):

                return x - 7


def get_stacks(distance):
    distance += 20

    '''
    匀加速\减速运行
        v = v0 + a * t
    
    位移:
    s = v * t + 0.5 * a * (t**2)
    '''

    # 初速度
    v0 = 0

    # 加减速度列表
    a_list = [3, 4, 5]

    # 时间
    t = 0.2

    # 初始位置
    s = 0

    # 向前滑动轨迹
    forward_stacks = []

    mid = distance * 3 / 5

    while s < distance:
        if s < mid:
            a = a_list[random.randint(0, 2)]

        else:
            a = -a_list[random.randint(0, 2)]

        v = v0

        stack = v * t + 0.5 * a * (t ** 2)

        # 每次拿到的位移
        stack = round(stack)

        s += stack

        v0 = v + a * t


        forward_stacks.append(stack)


    back_stacks = [-1, -1, -2, -3, -2, -3 ,-2, -2, -3, -1]

    return {'forward_stacks': forward_stacks, 'back_stacks': back_stacks}



def main():
    try:

        driver.get('https://passport.cnblogs.com/user/signin')
        driver.implicitly_wait(5)

        # 1.输入用户名与密码,点击登录
        username = driver.find_element_by_id('input1')
        password = driver.find_element_by_id('input2')
        login_button = driver.find_element_by_id('signin')
        username.send_keys('_tank_')
        password.send_keys('*********')
        login_button.click()

        # 2.点击滑动验证按钮,获取图片
        geetest_button = driver.find_element_by_class_name('geetest_radar_tip')
        geetest_button.click()

        time.sleep(0.2)

        # 3.针对完整的图片进行截取
        image1 = get_image1(driver)

        # 4.针对有缺口的图片进行截取
        image2 = get_image2(driver)

        # 5.对比两张图片,获取滑动距离
        distance = get_distance(image1, image2)

        # 6.模拟人为滑动轨迹
        stacks = get_stacks(distance)

        # 7.根据滑动轨迹进行滑动
        forward_stacks = stacks['forward_stacks']
        back_stacks = stacks['back_stacks']

        slider_button = driver.find_element_by_class_name('geetest_slider_button')
        time.sleep(0.2)

        ActionChains(driver).click_and_hold(slider_button).perform()

        time.sleep(0.2)
        for forward_stack in forward_stacks:
            ActionChains(driver).move_by_offset(xoffset=forward_stack, yoffset=0).perform()

        for back_stack in back_stacks:
            ActionChains(driver).move_by_offset(xoffset=back_stack, yoffset=0).perform()

        time.sleep(0.2)

        ActionChains(driver).move_by_offset(xoffset=5, yoffset=0).perform()
        ActionChains(driver).move_by_offset(xoffset=-5, yoffset=0).perform()

        ActionChains(driver).release().perform()



        time.sleep(50)




    finally:
        driver.close()

 

posted @ 2019-04-22 17:49  Zhuang_Z  阅读(875)  评论(1编辑  收藏  举报