python爬虫滑动验证码 python selenium 滑块验证码_Selenium

 

在项目中有时验证码是滑块拼图形式的,这种验证码该如何完成验证呢?

有以下几个步骤:

目录

第一步:得到验证码图片

第二步:匹配缺口照片在完整照片的位置

第三步:机器模拟人工滑动轨迹

第四步:判断拼图是否成功

第五步:滑块拼图递归循环调用

附录

 

一、得到验证码图片

1、思路

  • 获取完整图片和缺口图片的base64数据
  • 转换base64数据为图片

2、实践方法

封装

def get_images(self):
        """第一步:得到验证码图片base64数据"""

        # 得到完整的图片base64数据,"return"必须加上
        full_js = "return document.getElementsByTagName('img')[0].src"
        full_image = self.executeScript(full_js, loc=None)
        # 得到缺口的图片base64数据
        gap_js = "return document.getElementsByTagName('img')[1].src"
        gap_image = self.executeScript(gap_js, loc=None)
        # 设置保存路径
        base_path = fun().upPath() + "/data/image"
        full_path = base_path + "/full_image.png"
        gap_path = base_path + "/gap_image.png"
        # 转换
        self.base64_to_image(full_image, full_path)
        self.base64_to_image(gap_image, gap_path)
        # 返回路径
        return full_path, gap_path


    def base64_to_image(self,base64_str , image_path=None):
        """在第一步里:base64转化为image"""

        base64_data = re.sub('^data:image/.+;base64,', '', base64_str)
        byte_data = base64.b64decode(base64_data)
        image_data = BytesIO(byte_data)
        img = Image.open(image_data)
        if image_path:
            img.save(image_path)
        return img

完整的图片:full_image.png

python爬虫滑动验证码 python selenium 滑块验证码_Python_02

缺口的图片:gap_image.png

python爬虫滑动验证码 python selenium 滑块验证码_python爬虫滑动验证码_03

二、匹配缺口照片在完整照片的位置  返回目录

1、思路

  • 读取完整图片和缺口图片信息
  • 匹配缺口照片在完整照片的位置

2、实践方法

封装

def match_gaps(self, full, gap):
        """第二步:匹配缺口照片在完整照片的位置"""

        # 读取图片文件信息
        img_full = cv2.imread(full)
        # 以灰度模式加载图片
        template = cv2.imread(gap)
        # 方法
        methods = [cv2.TM_SQDIFF_NORMED, cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF_NORMED]
        # 记录每个方法的距离
        left = []
        # 最接近值
        min_ = []
        for method in methods:
            # 匹配
            res = cv2.matchTemplate(img_full, template, method)
            # 获取相关内容
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
            if method == cv2.TM_SQDIFF_NORMED:
                min_.append(min_val - 0.0)
                left.append(min_loc[0])
            else:
                min_.append(1.0 - max_val)
                left.append(max_loc[0])
        index = min_.index(numpy.min(min_))
        print("选用第{:d}个方法, 差为:{:f},距离为:{:d}".format(index+1, min_[index], left[index]))
        return left[index]

三、机器模拟人工滑动轨迹  返回目录

1、思路

  • 滑块移动轨迹
  • 机器模拟人工滑动轨迹

2、实践方法

封装

def sliding_track(self, distance):
        """第三步:机器模拟人工滑动轨迹"""

        # 按住按钮
        self.click_and_hold(loc.verifyButton_loc)
        # 获取轨迹
        track = self.get_track(distance)
        print(f"获取轨迹:{track}")
        print("++++++++++++++++++++++++++++++++++++++++++++")
        for t in track:
            self.move_by_offset(t)
        self.move_by_offset(5)
        self.move_by_offset(-5)
        # 松开按钮
        self.release()


    def get_track(self, distance):
        """在第三步里:滑块移动轨迹"""
        track = []
        current = 0
        # 阈值
        mid = distance * 3 / 4
        t = random.randint(5, 6) / 10
        v = 0
        while current < distance:
            if current < mid:
                a = 6
            else:
                a = -7
            v0 = v
            v = v0 + a * t
            move = v0 * t + 3 / 4 * a * t * t
            current += move
            track.append(round(move))
        return track

四、判断拼图是否存在  返回目录

1、思路

  • 判断拼图是否存在
  • 存在的话返回true

2、实践方法

封装

def judgeBox(self):
        """第四步:判断拼图是否存在"""

        box_js = "return document.getElementsByClassName('verifybox')"
        box_is = self.executeScript(box_js, loc=None)
        return len(box_is) > 0

五、滑块拼图递归循环调用  返回目录

1、思路

  • 判断拼图存在的话重新再执行以上方法

2、实践方法

封装

def loop(self):
        """第五步:滑块拼图递归循环调用"""

        # 得到验证码图片
        full_img_path, gap_img_path = self.get_images()
        # 匹配缺口照片在完整照片的位置
        number = self.match_gaps(full_img_path, gap_img_path)
        print(f"缺口照片的位置为:{number}")
        # 机器模拟人工滑动轨迹
        self.sliding_track(number)
        if self.judgeBox():
            self.loop()

滑动结果:

虽然现在能达到模拟人工进行滑动模块,但是成功率不是很高!