破解极验登录滑动验证(博客园登录)

from selenium import webdriver  # 用来驱动浏览器的
from selenium.webdriver import ChromeOptions
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
import random
from PIL import Image
import time

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

# 截取图片
def cup_image(driver):

    # 保存浏览器全屏图片
    driver.save_screenshot('xxx.png')

    image = driver.find_element_by_class_name('geetest_canvas_img')

    # 获取图片的上下左右坐标
    left = image.location['x']
    top = image.location['y']

    right = left + image.size['width']
    buttom = top + image.size['height']
    print(left, top, right, buttom)

    # 获取屏幕图片对象
    image_obj = Image.open('xxx.png')

    # 开始截取图片
    image1 = image_obj.crop((left, top, right, buttom))

    # image1.show()

    return image1

# 获取没有缺口的图片
def get_image1(driver):
    # print(1111)

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

    driver.execute_script(js)

    time.sleep(1)

    image1 = cup_image(driver)

    time.sleep(1)

    return image1

# 获取有缺口的图片
def get_image2(driver):
    # print(1111)

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

    driver.execute_script(js)

    time.sleep(1)

    image2 = cup_image(driver)

    time.sleep(1)

    return image2

# 对比两张图片获取滑动距离
def get_distance(img1, img2):

    # 滑动初始值
    start = 60

    # 像素差值
    color_num = 60

    # 循环遍历图片的宽与高获取每一个位置的x与y轴
    for x in range(start, img1.size[0]):
        for y in range(img1.size[1]):

            # 获取图片1每个坐标的像素
            rgb1 = img1.load()[x, y]
            # 获取图片2每个坐标的像素
            rgb2 = img2.load()[x, y]

            # print(rgb1, rgb2)
            # 获取像素的绝对值
            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_move(distance):

    # 增加划过的距离
    distance += 20

    '''
    1.计算当前速度
        
        当前速度 = 初速度 + 加/减速度 * 时间
        v = V0 + a * t
    
    2.计算位移
        位移 = 速度 * 时间 + 二分之一 * 加/减速度 * 时间的平方
        s = v * t + 0.5 * a * (t * t)
        s = v * t + 0.5 * a * (t ** 2)
        
    '''

    # 初速度
    v0 = 0

    # 速度列表
    a_list = [2, 3, 4]

    # 时间
    t = 0.2

    # 人的滑动轨迹列表
    move_list = []

    # 初始位移
    s = 0

    # 中间值
    mid = distance * 0.6

    # 判断如果位移小于总距离
    while s < distance:
        if s < mid:
            a = a_list[random.randint(0, 2)]
        else:
            a = -a_list[random.randint(0, 2)]

        # 计算当前速度 v = V0 + a * t
        v = v0

        # 计算位移 s = v * t + 0.5 * a * (t ** 2)
        move = v0 * t + 0.5 * a * (t ** 2)

        # 去掉小数
        move = round(move)

        # 把当前速度替换给初始速度
        v0 = v + a * t

        # 替换初始位移
        s += move

        # 追加每次循环的位移
        move_list.append(move)

    # 回退列表
    back_list = [-1, -2, -1, -1, -2, -3, -3, -2, -2, -1, -1, -1]

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

def main():

    driver = webdriver.Chrome(chrome_options=option)
    try:
        login_url = 'https://account.cnblogs.com/signin?returnUrl=https%3A%2F%2Fwww.cnblogs.com%2F'
        driver.get(login_url)
        driver.implicitly_wait(10)

        # 1、输入用户名与密码,并点击登录
        user = driver.find_element_by_id('LoginName')
        pwd = driver.find_element_by_id('Password')

        user.send_keys('用户名')
        pwd.send_keys('密码')

        time.sleep(1)

        button = driver.find_element_by_id('submitBtn')
        button.click()

        time.sleep(3)

        # 2、获取没有缺口的图片
        image1 = get_image1(driver)

        # 3、获取有缺口的图片
        image2 = get_image2(driver)

        # 4、对比两张图片获取滑动的距离
        distance = get_distance(image1, image2)
        print(distance)

        # 5、模拟人的滑动轨迹
        move_dict = get_move(distance)

        # 前进的轨迹
        move_list = move_dict.get('move_list')

        # 后退的轨迹
        back_list = move_dict.get('back_list')

        move_button = driver.find_element_by_class_name('geetest_slider_button')

        # 按住滑动按钮
        ActionChains(driver).click_and_hold(move_button).perform()

        # 6、开始滑动

        # 前进
        for x in move_list:
            ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
            time.sleep(0.1)

        time.sleep(0.1)

        # 后退
        for x in back_list:
            ActionChains(driver).move_by_offset(xoffset=x, 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()

        # 7、释放动作链
        ActionChains(driver).release().perform()

        time.sleep(1000)

    finally:
        driver.close()


if __name__ == '__main__':
    main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值