• 利用selenium库自动执行滑动验证码模拟登陆


    破解流程

    #1、输入账号、密码,然后点击登陆
    #2、点击按钮,弹出没有缺口的图
    #3、针对没有缺口的图片进行截图
    #4、点击滑动按钮,弹出有缺口的图
    #5、针对有缺口的图片进行截图
    #6、对比两张图片,找出缺口,即滑动的位移
    #7、按照人的行为行为习惯,把总位移切成一段段小的位移
    #8、按照位移移动
    #9、完成登录
    

    模拟登陆案例一:

    from selenium import webdriver
    from selenium.webdriver import ActionChains
    from PIL import Image
    import time
    import random
    option = webdriver.ChromeOptions()
    # 添加启动参数 (add_argument)
    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')
        # location 代表该图片在整个页面所在的位置(x, y),x:距离左边多长,y:距离上面多长
        # print(img.location)
        # size 代表该图片的大小
        # print(img.size)
    
        left = img.location.get('x')
        upper = img.location.get('y')
    
        right = left + img.size.get('width')
        lower = upper + img.size.get('height')
    
        # 拿到图片四个边的位置,就可以进行裁剪图片了
        # print(left, upper, right, lower)
        img_obj = Image.open('snap.png')
    
        # 对屏幕进行裁剪,获取滑动验证码图片
        image = img_obj.crop((left, upper, right, lower))
        # image.show()
    
        return image
    
    # 获取完整图片
    def get_img1(driver):
        time.sleep(0.2)
        js_code = """
            var x = document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display="block";
            console.log(x)
        """
    
        # 执行js代码
        driver.execute_script(js_code)
        time.sleep(1)
        # 截取图片
        img_obj = get_snap(driver)
    
        return img_obj
    
    # 获取有缺口的图片
    def get_img2(driver):
        time.sleep(0.2)
        js_code = """
            var x = document.getElementsByClassName('geetest_canvas_fullbg')[0].style.display="none";
            console.log(x)
        """
    
        # 执行js代码
        driver.execute_script(js_code)
        time.sleep(1)
        # 截取图片
        img_obj = get_snap(driver)
    
        return img_obj
    
    
    def get_distance(img1, img2):
        # 初始值
        start = 60
    
        # 模块色差
        color_num = 60
        for x in range(start, img1.size[0]):
            for y in range(img1.size[1]):
                rgb1 = img1.load()[x, y]
                rgb2 = img2.load()[x, y]
    
                # abs 获取绝对值
                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  # 误差值大概为7
    
    
    
    def get_stacks(distance):
        distance += 20
        '''
            拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速
            变速运动基本公式:
            ① v=v0+at       匀加速减速运行
            ② s=v0t+½at²    位移
            ③ v²-v0²=2as    
         '''
        # 初速度
        v0 = 0
    
        # 加减速度列表
        a_list = [50, 65, 80]
    
        # 时间
        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)
    
        # 往后返回20距离,因为之前distance向前多走了20
        back_stacks = [-5, -5, -5, -5,]
    
        return {'forward_stacks': forward_stacks, 'back_stacks': back_stacks}
    
    
    if __name__ == '__main__':
        try:
            driver.get('https://account.cnblogs.com/signin')
            # 隐式等待
            driver.implicitly_wait(5)
    
            # 步骤一:找到输入账户框
            user_input = driver.find_element_by_id('LoginName')
    
            # 步骤二:找到输入密码框
            pwd_input = driver.find_element_by_id('Password')
    
            user_input.send_keys('123456@qq.com')
            time.sleep(1)
            pwd_input.send_keys('123456')
            # 步骤三:找到确认登录按钮,并点击
            login_btn = driver.find_element_by_id('submitBtn')
            time.sleep(1)
            login_btn.click()
            time.sleep(3)
    
            # 步骤四: 拿到没有缺口的图片并截取
            img1 = get_img1(driver)
    
            # 步骤五: 拿到有缺口的图片并截取
            img2 = get_img2(driver)
    
            # 步骤六: 对比两张图片,获取滑动距离
            distance = get_distance(img1, img2)
    
            # 步骤七: 模拟人为滑动轨迹
            stacks = get_stacks(distance)
    
            # 步骤八: 根据滑动轨迹进行滑动
            forward_stacks = stacks['forward_stacks']
            back_stacks = stacks['back_stacks']
    
            # 步骤九:找到滑动按钮,并点击与hole住
            slider_btn = driver.find_element_by_class_name('geetest_slider_button')
            time.sleep(0.2)
            ActionChains(driver).click_and_hold(slider_btn).perform()
            time.sleep(0.2)
    
            # 步骤十:开始循环向前滑动
            for forward_stack in forward_stacks:
                ActionChains(driver).move_by_offset(xoffset=forward_stack, yoffset=0).perform()
                time.sleep(0.1)
            # 步骤十一:开始循环向后滑动20
            for back_stack in back_stacks:
                ActionChains(driver).move_by_offset(xoffset=back_stack, yoffset=0).perform()
                time.sleep(0.1)
    
            time.sleep(0.2)
    
    
            # 步骤十二:为了防止极验检测到,再将滑块前后小浮动5位置,再释放
    
            ActionChains(driver).move_by_offset(xoffset=5, yoffset=0).perform()
            time.sleep(0.2)
            ActionChains(driver).move_by_offset(xoffset=-5, yoffset=0).perform()
    
            # 可能会出现识别不了,说图片被怪物吃了,上面模拟人的行为都不要了,拿到距离后,直接执行下面代码,一步滑到缺口处即可
            # ActionChains(driver).move_by_offset(xoffset=distance, yoffset=0).perform()
    
            ActionChains(driver).release().perform()
    
            time.sleep(50)
    
        finally:
            driver.close()
    
  • 相关阅读:
    斯坦福ML公开课笔记15—隐含语义索引、神秘值分解、独立成分分析
    [cocos2d-x]屏幕自适应解决的方法
    【机器学习实验】学习Python来分类现实世界的数据
    按花生酱,赞不绝口——敏捷12准则的敏捷解释
    linux命令笔记之ls
    HTML5 Canvas动画效果实现原理
    互联网+时代的人生必修课—逆商
    WebService的相关使用
    将一个链表中的结点依照奇偶分成两个链表
    web开发性能优化---用户体验篇
  • 原文地址:https://www.cnblogs.com/guapitomjoy/p/12150997.html
Copyright © 2020-2023  润新知