Python入门day7

破解极验滑动验证

Python入门day7
''''''

'''

破解极验滑动验证

破解极验滑动验证

博客园登录url:

    https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F

 

代码逻辑:

1、输入用户名与密码,并点击登录

2、弹出滑动验证,获取有缺口与完整的图片

3、通过像素点进行比对,获取滑动位移距离

4、模拟人的行为轨迹

5、开始滑动

     

'''

from selenium import webdriver  # 用来驱动浏览器的

from selenium.webdriver import ActionChains  # 破解滑动验证码的时候用的 可以拖动图片

import time

from PIL import Image  # pip3 install pillow

import random

 

# 截图图片函数

def cut_image(driver):

    # 获取整个页面图片,图片名字为'snap.png'

    driver.save_screenshot('snap.png')

 

    # 获取滑动小画图

    image = driver.find_element_by_class_name('geetest_canvas_img')

    print(image.location)

    print(image.size)

 

    # 获取小图片的左上右下的位置

    left = image.location['x']

    top = image.location['y']

    right = left + image.size['width']

    buttom = top + image.size['height']

    print(left, top, right, buttom)

 

    # 调用open方法打开全屏图片并赋值给image_obj对象

    image_obj = Image.open('snap.png')

 

    # 通过image_obj对象对小图片进行截取

    # box: The crop rectangle, as a (left, upper, right, lower)-tuple.

    img = image_obj.crop((left, top, right, buttom))

    # 打开截取后的小图片

    # img.show()

    return img

 

# 获取完整图片

def get_image1(driver):

    time.sleep(2)

 

    # 修改document文档树,把完整图片的display属性修改为block

    js_code = '''

        var x = document.getElementsByClassName("geetest_canvas_fullbg")[0].style.display = "block";

    '''

 

    # 执行js代码

    driver.execute_script(js_code)

 

    # 截取图片

    image = cut_image(driver)

 

    return image

 

# 获取有缺口图片

def get_image2(driver):

    time.sleep(2)

 

    # 修改document文档树,把完整图片的display属性修改为block

    js_code = '''

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

    '''

 

    # 执行js代码

    driver.execute_script(js_code)

 

    # 截取图片

    image = cut_image(driver)

 

    return image

 

# 获取滑块滑动距离

def get_distance(image1, image2):

    # 小滑块右侧位置

    start = 60

 

    # 像素差

    num = 60

    print(image1.size)

    for x in range(start, image1.size[0]):

        for y in range(image1.size[1]):

 

            # 获取image1完整图片每一个坐标的像素点

            rgb1 = image1.load()[x, y]

 

            # 获取image2缺口图片每一个坐标的像素点

            rgb2 = image2.load()[x, y]

            # (60, 86, 40) (60, 86, 40) rgb

            print(rgb1, rgb2)

 

            # abs获取绝对值, 像素点比较的值

            r = abs(rgb1[0] - rgb2[0])

            g = abs(rgb1[1] - rgb2[1])

            b = abs(rgb1[2] - rgb2[2])

 

            # 如果条件成立,则找到缺口位置

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

                # 有误差 - 7像素

                return x - 7

 

# 模拟人的滑动轨迹

def get_strck_move(distance):

    distance += 20

 

    '''

    滑动行为轨迹

    加速公式:

        v = v0 + a * t

         

    路程公式:

        s = v0 * t + 0.5 * a * (t ** 2)

    '''

 

    # 初速度

    v0 = 0

 

    # 时间

    t = 0.2

 

    # 位置

    s = 0

 

    # 滑动轨迹列表 向前滑动列表

    move_list = []

 

    # 中间值,作为加减速度的位置

    mid = distance / 5 * 3

 

    # 加减速度列表

    v_list = [1, 2, 3, 4]

 

    # 循环位移

    while s < distance:

        if s < mid:

            # 随机获取一个加速度

            a = v_list[random.randint(0, len(v_list) - 1)]

 

        else:

            # 随机获取一个减速度

            a = -v_list[random.randint(0, len(v_list) - 1)]

 

        '''

        匀加速\减速运行

        v = v0 + a * t

 

        位移:

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

        '''

        # 获取初始速度

        v = v0

 

        # 路程公式:

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

        s1 = round(s1)  # 取整

 

        # 加速公式:

        # v = v0 + a * t

        m_v = v + a * t

 

        # 把当前加/减速度赋值给初始速度,以便下一次计算

        v0 = m_v

 

        # 把位移添加到滑动列表中

        move_list.append(s1)

 

        # 修改滑动初始距离

        s += s1

 

    # 后退列表, 自定义后退滑动轨迹,必须是负值

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

 

    return {'move_list': move_list, 'back_list': back_list}

 

def main():

    driver = webdriver.Chrome(r'D:\BaiduNetdiskDownload\chromedriver_win32\chromedriver.exe')

    driver.implicitly_wait(10)

    try:

        driver.get('https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F')

 

        # 1、输入用户名与密码,并点击登录

        user_input = driver.find_element_by_id('LoginName')

        user_input.send_keys('_tank_')

        time.sleep(0.2)

 

        pwd_input = driver.find_element_by_id('Password')

        pwd_input.send_keys('k46709394.')

        time.sleep(2)

 

        login_submit = driver.find_element_by_id('submitBtn')

        login_submit.click()

 

        # 2、获取完整的图片

        image1 = get_image1(driver)

 

        # 3、获取有缺口图片

        image2 = get_image2(driver)

 

        # 4、比对两张图片,获取滑动距离

        distance = get_distance(image1, image2)

        print(distance)

 

        # 5、模拟人的滑动轨迹

        move_dict = get_strck_move(distance)

        # 获取前进滑动轨迹

        move_list = move_dict['move_list']

        # 获取后退滑动轨迹

        back_list = move_dict['back_list']

 

        # 6、开始滑动

        move_tag = driver.find_element_by_class_name('geetest_slider_button')

        # 点击摁住滑动按钮

        ActionChains(driver).click_and_hold(move_tag).perform()

 

        # 向前滑动

        for move in move_list:

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

            time.sleep(0.1)

 

        time.sleep(0.1)

 

        # 向后滑动

        for back in back_list:

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

            time.sleep(0.1)

 

        # 制作微妙晃动

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

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

 

        time.sleep(0.1)

 

        # 释放滑动按钮

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

 

        time.sleep(100)

 

    finally:

        driver.close()

 

if __name__ == '__main__':

    main()
View Code

今日总结

    通过获取有缺口与完整的图片,将他们的像素进行对比,获取滑动位移距离来模拟人的行为轨迹,实现了破解极验滑动验证,代码虽然复杂,但是掌握原理之后,思维逻辑日渐清晰。

上一篇:易用宝项目记录day7-权限与菜单


下一篇:day7