zoukankan      html  css  js  c++  java
  • selenium之滑块验证码破解代码详解

    PS:浏览器和电脑的缩放应该调为100%(Windows默认为125%),否则可能会导致获取局部图片时出现误差!
    from selenium import webdriver
    from selenium.webdriver.common.action_chains import ActionChains
    from PIL import Image
    import time
    
    def get_snapshot():
        "获取整个页面的快照,并返回图片对象"
        driver.save_screenshot('snapshot.png')
        pic_obj = Image.open('snapshot.png')
        return pic_obj
    
    def get_image():
        # 获取滑块验证码图片所在div的元素对象
        element = driver.find_element_by_xpath('//div[@class="geetest_slicebg geetest_absolute"]')
        # 计算滑块验证码部分截图的坐标
        left = element.location['x']
        top = element.location['y']
        right = left + element.size['width']
        bottom = top + element.size['height']
        # 先获取整个界面截图的对象
        pic_obj = get_snapshot()
        # 获取滑块验证码部分截图对象
        part_pic_obj = pic_obj.crop((left, top, right, bottom))
        return part_pic_obj
    
    def get_distance(image1, image2):
        '''
        拿到滑动验证码需要移动的距离
        :param image1:没有缺口的图片对象
        :param image2:带缺口的图片对象
        :return:需要移动的距离
        '''
        # 从图像的左侧60像素开始匹配,把填充的那部分去掉,不比较,避免干扰。
        left = 60
        for i in range(left, image1.size[0]):  # 图像的宽
            for j in range(image1.size[1]):  # 图像的高
                rgb1 = image1.load()[i, j]
                rgb2 = image2.load()[i, j]
                res1 = abs(rgb1[0] - rgb2[0])
                res2 = abs(rgb1[1] - rgb2[1])
                res3 = abs(rgb1[2] - rgb2[2])
                # 自定义容差为60定义为缺口
                if res1 >= 60 and res2 >= 60 and res3 >= 60:
                    return i - 7  # 误差大概是7
        return left
    
    
    def get_tracks(distance):
        '''
        拿到移动轨迹,模仿人的滑动行为,先匀加速后匀减速
        匀变速运动基本公式:
        ①v=v0+at
        ②s=v0t+½at²
        ③v²-v0²=2as
        :param distance: 需要移动的距离
        :return: 存放每0.2秒移动的距离
        '''
        # 初速度
        v = 0
        # 单位时间为0.2s来统计轨迹,轨迹即0.2内的位移
        t = 0.2
        # 位移/轨迹列表,列表内的一个元素代表0.2s的位移
        tracks = []
        # 当前的位移
        current = 0
        # 到达mid值开始减速
        mid = distance * 4 / 5
        while current < distance:
            if current < mid:
                # 加速度越小,单位时间的位移越小,模拟的轨迹就越多越详细
                a = 2
            else:
                a = -3
            # 初速度
            v0 = v
            # 0.2秒时间内的位移
            s = v0 * t + 0.5 * a * (t ** 2)
            # 当前的位置
            current += s
            # 添加到轨迹列表
            tracks.append(round(s))
            # 速度已经达到v,该速度作为下次的初速度
            v = v0 + a * t
        return tracks
    
    if __name__ == '__main__':
        try:
            driver = webdriver.Chrome()
            driver.get('https://account.ch.com/NonRegistrations-Regist')
            driver.maximize_window()
            driver.find_element_by_name('phoneNumberInput').send_keys('15216122411')
    
            # 单击,让滑块验证码的图片显示
            getDynamicPwd = driver.find_element_by_xpath('//a[@id="getDynamicPwd"]')
            ActionChains(driver).move_to_element(getDynamicPwd).move_by_offset(5, 0).click().perform()
            # driver.find_element_by_xpath('//a[@id="getDynamicPwd"]').click()
            # driver.execute_script('document.getElementById("getDynamicPwd").click()')
            # driver.find_element_by_id('getDynamicPwd').click()
    
            time.sleep(2)  # 沉睡两秒,加载滑块验证码
    
            # 获取有缺口的滑块验证局部截图
            image1 = get_image()
            image1.save('imag1.png')  # 获取局部截图
    
            # 获取没有缺口的图片
            driver.execute_script('document.getElementsByClassName("geetest_canvas_fullbg")[0].style="display:block"')
            image2 = get_image()
            image2.save('imag2.png')  # 获取局部截图
    
            distance = get_distance(image1, image2)
    
            # 获取滑块
            huakuai = driver.find_element_by_xpath('//div[@class="geetest_slider_button"]')
    
            # 拉动滑块开始执行
            ActionChains(driver).click_and_hold(on_element=huakuai).perform()
            ActionChains(driver).move_by_offset(xoffset=distance * 0.5, yoffset=0).perform()  # 闪现50%
    
            # 模拟人的行为习惯(先匀加速拖动后匀减速拖动),把需要拖动的总距离分成一段一段小的轨迹
            tracks = get_tracks(distance * 0.5)  # 剩下的50%在模拟移动
            for x in tracks:
                ActionChains(driver).move_by_offset(xoffset=x, yoffset=0).perform()
            else:
                ActionChains(driver).move_by_offset(xoffset=3, yoffset=0).perform()  # 先移过一点
                ActionChains(driver).move_by_offset(xoffset=-3, yoffset=0).perform()  # 再退回来,看上去更像人为
    
            # 0.5s释放鼠标
            time.sleep(0.5)
            ActionChains(driver).release().perform()
    
        except Exception as error:
            print(error)
            driver.close()
    
    
    
     
    
    
    


  • 相关阅读:
    传参问题-HttpMessageNotReableException
    排序03-简单排序法
    排序02-直接插入排序法
    排序01-冒泡排序法
    书摘
    CS229
    SLAM学习笔记
    形态学图像处理
    SLAM学习笔记
    SLAM学习笔记
  • 原文地址:https://www.cnblogs.com/Liu928011/p/14948003.html
Copyright © 2011-2022 走看看