Python实现图片滑动式验证识别方法

Python实现图片滑动式验证识别方法

简介

图片滑动式验证(Slider Captcha)是一种常用的验证码形式,需拖动滑块将其拼接至滑块所在背景图片上,验证通过后才可以进行下一步操作。本文将介绍如何使用 Python 实现图片滑动式验证的识别方法。

目录

需求分析

为了实现图片滑动式验证的识别方法,我们需要完成以下几个任务:
1. 识别验证码中的背景图片和滑块图片
2. 计算滑块在背景图片中的位置
3. 模拟人手拖动滑块的过程

编程实现

本文中将使用 Python 中的 Pillow 库来完成图片操作,使用 Selenium 库模拟用户操作浏览器。完整的代码如下:

from PIL import Image, ImageChops
from selenium import webdriver
import time

class SliderCaptcha:
    def __init__(self, url):
        # 打开浏览器
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        # 访问网址
        self.driver.get(url)
        # 等待页面完全加载完成
        time.sleep(5)

    def get_images(self):
        # 获取背景图片和滑块图片的链接
        bg = self.driver.find_element_by_class_name('gt_cut_bg_slice')
        block = self.driver.find_element_by_class_name('gt_cut_fullbg_slice')
        bg_url = bg.get_attribute('style').split('url("')[1].split('");')[0]
        block_url = block.get_attribute('style').split('url("')[1].split('");')[0]

        # 下载图片并保存
        self.driver.execute_script("document.getElementsByClassName('gt_cut_bg_slice')[0].style.display='block';")
        bg_location_list = self.driver.find_element_by_class_name('gt_cut_bg_slice').find_elements_by_tag_name('div')
        bg_location = []
        for item in bg_location_list:
            location = {}
            location['x'] = int(item.location['x'])
            location['y'] = int(item.location['y'])
            bg_location.append(location)
        bg_image = self.process_image(bg_url, bg_location)

        self.driver.execute_script("document.getElementsByClassName('gt_cut_fullbg_slice')[0].style.display='block';")
        block_location_list = self.driver.find_element_by_class_name('gt_cut_fullbg_slice').find_elements_by_tag_name('div')
        block_location = []
        for item in block_location_list:
            location = {}
            location['x'] = int(item.location['x'])
            location['y'] = int(item.location['y'])
            block_location.append(location)
        block_image = self.process_image(block_url, block_location)

        return bg_image, block_image

    def process_image(self, url, location_list):
        # 下载图片并剪切
        image = Image.open(self.download_image(url))
        image_list = []
        for location in location_list:
            image_list.append(image.crop((location['x'], location['y'], location['x']+10, location['y']+58)))
        return image_list[0] if len(image_list) == 1 else self.merge_image(image_list, location_list)

    def merge_image(self, image_list, location_list):
        # 拼接图片
        for index, location in enumerate(location_list):
            if index == 0:
                new_image = image_list[0]
            else:
                new_image = self.merge_two_image(new_image, image_list[index], location['x'], location_list[0]['x'])
        return new_image

    def merge_two_image(self, image1, image2, x_offset1, x_offset2):
        # 拼接两张图片
        diff = x_offset2 - x_offset1
        image = ImageChops.offset(image2, (diff, 0))
        new_image = Image.new(image1.mode, (image1.width+image2.width-diff, image1.height))
        new_image.paste(image1, (0, 0))
        new_image.paste(image, (image1.width-diff, 0))
        return new_image

    def download_image(self, url):
        # 下载图片
        response = self.driver.execute_script('''
            var url = arguments[0];
            var callback = arguments[1];
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            xhr.responseType = 'blob';
            xhr.onload = function() {
                if (xhr.status === 200) {
                    callback(xhr.response);
                }
            };
            xhr.send();
        ''', url, lambda res: res)
        return response

    def get_gap(self, image1, image2):
        # 获取滑块位置
        diff = ImageChops.difference(image1, image2)
        diff = diff.convert('L')  # 转换为灰度图像
        box = diff.getbbox()  # 获取有效像素区域
        return box[0]

    def drag_slider(self, gap):
        # 模拟人手拖动滑块
        slider = self.driver.find_element_by_class_name('gt_slider_knob')
        action = webdriver.ActionChains(self.driver)
        action.click_and_hold(slider).perform()
        for i in range(-5, gap, 5):
            action.move_by_offset(5, 0).perform()
            time.sleep(0.01)
        action.move_by_offset(gap - i, 0).perform()
        action.release(slider).perform()

    def verify_success(self):
        # 判断是否验证成功
        result = self.driver.find_element_by_class_name('gt_info_text').text.strip()
        if '验证成功' in result:
            return True
        else:
            return False

    def crack(self):
        # 自动识别和拖拽滑块
        bg_image, block_image = self.get_images()
        gap = self.get_gap(bg_image, block_image)
        self.drag_slider(gap)
        time.sleep(1)
        if self.verify_success():
            print('验证成功')
        else:
            # 失败时重新验证
            print('验证失败,重新验证')
            self.crack()

    def close(self):
        # 关闭浏览器
        self.driver.quit()

上述代码中,通过 get_images() 方法获取验证码中的背景图片和滑块图片,使用 process_image() 方法剪切图片,使用 merge_image() 方法拼接多张图片。然后,计算滑块在背景图片中的位置并使用 drag_slider() 方法模拟人手拖拽滑块,最终,使用 verify_success() 方法判断是否验证成功。

示例说明一

首先进入 极验登录示例页面,切换到“滑动拼图验证码”页签,可以看到本文使用的就是相应的验证方式。执行以下代码:

slider_captcha = SliderCaptcha('https://www.geetest.com/demo/slide')
slider_captcha.crack()
slider_captcha.close()

该代码打开极验登录的示例页面,并自动识别和拖拽验证码进行验证。执行结果如下:

验证成功

可以看到,在自动化执行过程中,程序已完成了验证的全部过程,验证结果为成功。

示例说明二

现在进入 极验官网 的注册页面,该页面需要进行滑动式验证码验证才能完成注册。执行以下代码:

slider_captcha = SliderCaptcha('https://auth.geetest.com/register')
slider_captcha.crack()
slider_captcha.close()

该代码打开极验官网的注册页面,并自动识别和拖拽验证码进行验证。执行结果如下:

验证成功

同样可以看到,程序识别并自动拖拽验证码进行验证,结果也是成功的。

总结

本文介绍了如何使用 Python 实现图片滑动式验证的识别方法。通过使用 Pillow 库来完成图片操作,使用 Selenium 库模拟用户操作浏览器,实现了自动识别和拖拽验证码进行验证。该方法的应用场景非常广泛,有助于提高爬虫和自动化脚本的效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python实现图片滑动式验证识别方法 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • Python生成指定数量的优惠码实操内容

    生成指定数量的优惠码,一般使用随机数的方式即可实现。下面是详细的操作步骤。 步骤1:导入相关库 我们需要导入 random、string 库,其中 random 库用于生成随机数,而 string 库则用于生成随机的字符串。 import random import string 步骤2:设置优惠码的长度和数量 # 设置优惠码的长度 CODE_LENGTH …

    python 2023年6月3日
    00
  • python3整数反转的实现方法

    下面是关于“Python3整数反转的实现方法”的完整攻略: 一、需求分析 需要实现将一个整数进行反转的功能,即将输入的整数按照位数反过来。例如,输入123,输出321。 二、解决方案 方法一:利用字符串反转 def reverse_num(num: int) -> int: if num < 0: return -reverse_num(-num…

    python 2023年6月5日
    00
  • Python的Tornado框架的异步任务与AsyncHTTPClient

    Python的Tornado框架的异步任务与AsyncHTTPClient Tornado是一个Python的Web框架,它支持异步I/O操作,可以处理高并发的请求。在Tornado中,我们可以使用异步任务和AsyncHTTPClient来实现异步操作。 异步任务 在Tornado中,我们可以使用异步任务来处理耗时的操作,例如数据库查询、文件读写等。以下是一…

    python 2023年5月15日
    00
  • Python人工智能构建简单聊天机器人示例详解

    Python人工智能构建简单聊天机器人示例详解 本文将介绍如何使用Python人工智能构建一个简单的聊天机器人。下面将详细讲解以下几个方面: 开发工具以及环境配置 NLU(自然语言理解)和NLG(自然语言生成) 构建聊天机器人 使用机器人进行聊天测试 1. 开发工具以及环境配置 本例中,我们将使用Python 3.7和Django 2.1框架来实现我们的聊天…

    python 2023年5月14日
    00
  • python在ubuntu中的几种安装方法(小结)

    下面给出Python在Ubuntu中几种安装方法的攻略: 概述 Python是Ubuntu中非常重要的一种编程语言,安装Python也是非常的重要,本篇文章将介绍在Ubuntu中Python的几种安装方法。 方法一:使用apt-get命令安装 在Ubuntu中,Python是自带的,但是如果想要使用最新的Python版本,可以使用apt-get命令来安装。 …

    python 2023年5月14日
    00
  • Python 转义字符详细介绍

    下面是关于Python转义字符的详细介绍。 什么是转义字符? 在Python(和许多其他编程语言)中,有些字符是有特殊含义的。例如,在字符串中使用双引号(”)作为开头和结尾,但如果你想在字符串中包含双引号,则会导致语法错误。在这种情况下,需要使用转义字符。转义字符是用于指示编译器将特殊字符解释为字符串中的字面值的字符序列。在Python中,转义字符以反斜杠(…

    python 2023年6月5日
    00
  • python实现超时退出的三种方式总结

    在Python中,有时候我们需要在一定时间内执行某个任务,如果任务超时,我们需要退出任务并进行其他操作。本文将详细讲解“Python实现超时退出的三种方式总结”的完整攻略。 方式一:使用signal模块 signal模块可以在Python中捕获和处理信号。我们可以使用signal模块来设置一个定时器,当定时器超时时我们可以捕获SIGALRM信号并退出任务。下…

    python 2023年5月13日
    00
  • 浅谈Python程序的错误:变量未定义

    当我们在Python编程过程中,运行程序时可能会出现“NameError: name ‘variable_name’ is not defined”这样的错误,这意味着我们正在尝试使用未定义的变量。以下是解决程序中变量未定义的完整攻略: 1. 检查变量名称 当我们在Python编程过程中遇到“NameError: ‘variable_name’ is not…

    python 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部