Python反爬案例——验证码的识别

验证码的识别

使用打码平台识别验证码

利用打码平台可以轻松识别各种各样的验证码,图形验证码、滑动验证码、点选验证码和逻辑推理验证码。打码平台提供了一系列API,只需要向API上传验证码图片,它便会返回对应的识别结果。

使用超级鹰平台,官网:https://www.chaojiying.com/ ,首页如图所示:
在这里插入图片描述

超级鹰打码平台支持识别的内容包括但不限于:简单数字、字母、中文字符、滑动拼图验证等类型的验证码。同时,该平台还提供云端识别服务,可为所有软件提供验证码识别自动化解决方案,帮助客户进行验证码识别、远程答题、人工打码,以实现价值。

使用超级鹰打码平台进行验证码识别的步骤通常包括以下几点:

  • 注册并登录超级鹰打码平台的账号。
  • 下载需要识别的验证码图片,并将其保存在本地。
  • 调用平台提供的API或示例代码,将图片数据发送到超级鹰打码平台进行识别。
  • 接收平台返回的识别结果,并进行后续的操作。

通过这个平台,用户可以轻松地对各种类型的验证码进行识别,从而提高自动化流程的效率和准确性。

  1. 准备工作

安装两个Python库——opencv-python和Pillow,安装命令如下:

pip3 install opencv-python pillow

自行下载测试所用的验证码,地址为https://github.com/Python3WebSpider/CaptchaPlatform,可以先复制下来:

git clone [https://github.com/Python3WebSpider/CaptchaPlatform](https://github.com/Python3WebSpider/CaptchaPlatform).git

复制之后,本地出现一个CaptchaPlatform-master文件夹,内部存放的是测试需要的验证码图片。还有一个chaojiying.py文件,内容如下:

import requests
from hashlib import md5

class Chaojiying(object):
    
    def __init__(self, username, password, soft_id):
        self.username = username
        self.password = md5(password.encode('utf-8')).hexdigest()
        self.soft_id = soft_id
        self.base_params = {
            'user': self.username,
            'pass2': self.password,
            'softid': self.soft_id,
        }
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36',
        }
    
    def post_pic(self, im, codetype):
        """
        im: 图片字节
        codetype: 题目类型 参考 http://www.chaojiying.com/price.html
        """
        params = {
            'codetype': codetype,
        }
        params.update(self.base_params)
        files = {'userfile': ('ccc.jpg', im)}
        r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files,
                          headers=self.headers)
        return r.json()
    
    def report_error(self, im_id):
        """
        im_id:报错题目的图片ID
        """
        params = {
            'id': im_id,
        }
        params.update(self.base_params)
        r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
        return r.json()

定义了一个Chaojiying类,其构造方法接收三个参数。

  • username:超级鹰账户的用户名
  • password:超级鹰账户和密码
  • soft_id:软件ID,需要到超级鹰后台的“软件ID”中获取,如图所示,就生成一个软件ID928939:

在这里插入图片描述

这个类还实现了两个方法,post_pic方法用于上传验证码并获取识别结果,report_error方法用于上报识别错误,识别错误时不扣提分,就是不花钱。

以上内容都准备好后,开始识别验证码,首先是图像验证码。

在这里插入图片描述

  1. 图形验证码

这是一个由英文字母和数字组合而成的验证码,一共六位,查阅价格文档https://www.chaojiying.com/price.html,和这个验证码相符合的描述是“1-6位英文数字”,类型是“1006”,如图所示:

在这里插入图片描述

接着就可以编写实现代码:

from chaojiying import Chaojiying

"""
USERNAME、PASSWORD、SOFT_ID需要更改为自己的用户名、密码和软件ID
"""
USERNAME = 'lxw1973'
PASSWORD = '2~~~-**w'
SOFT_ID = '928939'
CAPTCHA_KIND = '1006'
FILE_NAME = 'captcha1.png'
client = Chaojiying(USERNAME, PASSWORD, SOFT_ID)
result = client.post_pic(open(FILE_NAME, 'rb').read(), CAPTCHA_KIND)
print(result)

这里首先利用USERNAME, PASSWORD和SOFT_ID三个信息初始化了一个Chaojiying对象,赋值为client变量,然后调用client的post_pic方法上传了图片中的二进制内容,这里把post_pic方法的第二个参数设置为CAPTCHA_KIND,即1006。

返回结果如下:

{'err_no': 0, 'err_str': 'OK', 'pic_id': '2246121180794820046', 'pic_str': '6m44nn', 'md5': '275d14cb7a43b2ce7c9aa1745be2aafd'}

可以看到,返回结果中的pic_str字段出现了正确的识别结果,识别成功。

  1. 点选验证码

12306的验证码就是非常典型的一种点选验证码。如下图所示的点选验证码:

在这里插入图片描述

比较符合这个验证码的描述是“坐标多选”,类型是“9004”,会返回1~4个坐标,如图所示:

在这里插入图片描述

将“图形验证码”代码中的CAPTCHA_KIND改为9004,FILE_NAME改成captcha2.png,然后重新运行代码,结果如下:

{'err_no': 0, 'err_str': 'OK', 'pic_id': '2246121320794820047', 'pic_str': '94,121|206,139', 'md5': 'b7ab91737bc958b6dd47bf63921a615d'}

可以看到返回结果中的pic_str字段变成了’94,121|206,139’,使用OpenCV技术在上图中标注出这个点:

import cv2

image = cv2.imread('captcha2.png')
image = cv2.circle(image, (94, 121), radius=10, color=(0,0,255), thickness=-1)
image = cv2.circle(image, (206,139), radius=10, color=(0,0,255), thickness=-1)
cv2.imwrite('captcha2_label_test.png', image)

运行结果如下图:

在这里插入图片描述

可以看到标注出来的正是第1张和第2张图片,没问题,验证成功!

另外,还有些验证码也属于点选类型,例如指定点击物品的颜色的验证码,如图所示:

在这里插入图片描述

指定文字点击顺序的验证码,如图所示:

在这里插入图片描述

要求按照语序点击文字的验证码,如图所示:

在这里插入图片描述

  1. 滑动验证码

我们再来验证滑块验证码,这里以下图为例进行讲解,如下图所示:

在这里插入图片描述

查阅价格文档,比较符合这个验证码的描述是“坐标选一”,类型是“9101”,如图所示:

在这里插入图片描述

和“点选验证码”类似,将“图形验证码”代码中国内地CAPTCHA_KIND改成9101,FILE_NAME改成captcha3.png,然后重新运行代码,得到如下结果:

{'err_no': 0, 'err_str': 'OK', 'pic_id': '1246122000794820048', 'pic_str': '204,90', 'md5': '66608b4a14544e3b3b36c56c94e1959d'}

可以看到返回结果中的pic_str字段变成了204,90,我们用OpneCV技术在例图上标注这个点:

import cv2

image = cv2.imread('captcha3.png')
image = cv2.circle(image, (204, 90), radius=10, color=(0,0,255), thickness=-1)
cv2.imwrite('captcha3_label_test.png', image)

返回结果如下图:

在这里插入图片描述

可以在图片上做一些处理,例如添加自定义的文字,提醒标注人员哪里是正确的位置。下面使用OpenCV技术在例图上加一行字“请点击目标缺口的左上角”:

import cv2
from PIL import ImageFont, ImageDraw, Image
import numpy as np
import io
from chaojiying import Chaojiying

USERNAME = 'lxw1973'
PASSWORD = '2~~~-**w'
SOFT_ID = '928939'
CAPTCHA_KIND = '9101'
def cv2_add_text(image, text, left, top, textColor=(255, 0, 0), text_size=20):
    image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(image)
    font = ImageFont.truetype('simsun.ttc', text_size, encoding='utf-8')
    draw.text((left, top), text, textColor, font=font)
    return cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)

image = cv2.imread('captcha3.png')
image = cv2_add_text(image, '请点击目标缺口的左上角', int(image.shape[1]/10), int(image.shape[0]/2), (255,0,0), 40)
client = Chaojiying(USERNAME, PASSWORD, SOFT_ID)

image = cv2.circle(image, (204, 90), radius=10, color=(0,0,255), thickness=-1)
client = Chaojiying(USERNAME, PASSWORD, SOFT_ID)
result = client.post_pic(io.BytesIO(cv2.imencode('.png', image)[1]).getvalue(), CAPTCHA_KIND)
print(result)

这里我们定义一个cv2_add_text方法,由于直接添加中文会产生乱码,所以需要借助Pillow库,并且依赖一个中文字体文件,添加文字后,图片如下所示:

在这里插入图片描述

重新运行代码,得到如下结果:

{'err_no': 0, 'err_str': 'OK', 'pic_id': '1246209360794820050', 'pic_str': '200,90', 'md5': '428e629f358f39a7d899a0f19a5852de'}

这时返回结果中的pic_str字段变成了200,90,标注一下这个点,结果如图所示:

在这里插入图片描述

  1. 问答验证码

再看一种验证码——问答验证码,样例图片入下图所示:

在这里插入图片描述

可以看到,验证码上有一个问题,并且在问题后的括号里有答案提示,问题中每个字的颜色、形状和字与字之间距离各不相同,背景中还有一些干扰线。

这种验证码,如果想自动化完成识别,难度是比较大的。首先需要识别出图片上的文字,这对正确率有很高的要求。在能正确提取所有文字并且问题相对简单的前提下,可以通过用爬虫模拟一些网络搜索操作获得结果。如果问题稍微复杂一些或者在网络上搜素不到答案,可以通过一些自然语言处理技术或者知识库获得答案。但总的来说,通过纯技术手段识别问答验证码的难度还是比较高的。

这样的验证码,比较合适的解决方案依然是打码平台,借助平台背后的人工力量完成识别。同样,查阅一下超级鹰平台对此类验证码的支持情况,如图所示:

在这里插入图片描述

可以看到6004类型是支持此类验证码的,我们把代码中的CAPTCHA_KIND改成6004,FILE_NAME改成captcha4.png,然后重新运行代码,得到如下结果:

from chaojiying import Chaojiying

"""
USERNAME、PASSWORD、SOFT_ID需要更改为自己的用户名、密码和软件ID
"""
USERNAME = 'lxw1973'
PASSWORD = '~~~~-**w'
SOFT_ID = '928939'
CAPTCHA_KIND = '6004'
FILE_NAME = 'captcha4.png'
client = Chaojiying(USERNAME, PASSWORD, SOFT_ID)
result = client.post_pic(open(FILE_NAME, 'rb').read(), CAPTCHA_KIND)
print(result)

运行结果如下:
{'err_no': 0, 'err_str': 'OK', 'pic_id': '2246210120794820051', 'pic_str': '大象', 'md5': '985c12e820556347a54f149111a40bba'}

返回结果中的pic_str字段是大象,回答正确,如此看来,打码平台着实非常强大。

更多的体验可以在小蜜蜂AI网站获取,网址为:https://zglg.work

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/508974.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

[win10]工具软件之HxD免费软件--把yuv图片数据保存成十六进制数组数据头文件

工具软件之HxD免费软件–把yuv图片数据保存成十六进制数组数据头文件 HxD把yuv图片数据保存成十六进制数组数据头文件 嵌入式ai算法集成测试时,经常需要对视频或者图片进行回灌挂测测试看算法效果。有些嵌入式设备不支持把数据导入到设备中,没有网络&a…

基于arkTS开发鸿蒙app应用案例——通讯录案例

1.项目所用技术栈 arkTS node.js express mongoDB 2.效果图 3.源码 Index.ets(登录页) 登陆时让前端访问数据库中已经存好的账号密码,如果可以查询到数据库中的数据,则账号密码正确,登录成功,否则登录…

Vue项目中引入html页面(vue.js中引入echarts数据大屏html [静态非数据传递!] )

在项目原有vue(例如首页)基础上引入html页面 1、存放位置 vue3原有public文件夹下 我这边是新建一个static文件夹 专门存放要用到的html文件 复制拖拽过来 index为html的首页 2、更改路径引入到vue中 这里用到的是 iframe 方法 不同于vue的 component…

springCloudAlibaba集成gateWay实战(详解)

一、初识网关? 1、网关介绍 ​ 在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去调用。这样的话…

3D DRAM在2025年来袭

4月1日消息,据半导体工程报道,在行业大会Memcon 2024上,三星电子宣布其计划成为首家在2025年后步入3D DRAM内存时代的行业领军者。随着DRAM内存行业在本十年后期将线宽压缩至低于10纳米,现有的设计解决方案在如此精细的尺度上难以…

渗透测试练习题解析 5(CTF web)

1、[安洵杯 2019]easy_serialize_php 1 考点:PHP 反序列化逃逸 变量覆盖 【代码审计】 通过 GET 的方式获取参数 f 的值,传递给变量 function 定义一个过滤函数,过滤掉特定字符(用空字符替换) 下面的代码其实没什么用…

【Android Studio3.5.2安装以及错误错误解决】

前言 下面是博主在安装Android studio时遇到的一些问题,并且花费很长时间寻找解决方法,经过了血和泪的教训下面将自己在安装过程中遇到的查看的资料贴出来(感谢各位大佬的文章帮助本闲狗解答疑惑,此处贴出原文链接,如…

Docker基础系列之TLS和CA认证

Docker基础系列之TLS和CA认证 文章目录 Docker基础系列之TLS和CA认证1. 引言2. 初识TLS和CA3. 开启TLS和CA认证3.1 生成证书3.2 配置TLS 4. 参考和感谢 1. 引言 我们日常工作当中会遇到这些需求: 监控Docker容器在idea开发工具中连接Docker,直接发布至…

【漏洞复现】Wordpress saveconfiguration接口处存在任意文件上传漏洞

免责声明:文章来源互联网收集整理,请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失,均由使用者本人负责,所产生的一切不良后果与文章作者无关。该…

String Encryptor custom Bean not found with name ‘jasyptStringEncryptor‘...

项目采用 spring boot 2.6.13 jasypt-spring-boot-starter 3.0.5 apollo-client 1.6.0 自定义jasyptStringEncryptor,服务器上启动死活报找不到bean jasyptStringEncryptor,采用默认的,密文配置项自然解密失败导致服务无法启动。 经过一…

计算机网络——33多点访问协议

多点访问协议 多路访问链路和协议 两种类型的链路(一个子网内部链路连接形式) 点对点 拨号访问的PPP以太网交换机和主机之间的点对点链路 广播 传统以太网HFC上行链路802.11无线局域网 多路访问协议 单个共享的广播型链路 2个过更多结点同时传送&am…

【C语言】联合和枚举

个人主页点这里~ 联合和枚举 一、联合体1、联合体类型的声明2、联合体成员的特点3、与结构体对比4、计算联合体大小 二、枚举1、枚举的声明2、枚举的优点3、枚举类型的使用 一、联合体 1、联合体类型的声明 联合体的定义与结构体相似,但是联合体往往会节省更多的空…

软考 - 系统架构设计师 - 数据流图案例题

阅读以下关于系统数据分析与建模的叙述,在答题纸上回答问题1至问题3。 【说明】 某公司正在研发一套新的库存管理系统。系统中一个关键事件是接收供应商供货。项目组系统分析员小王花了大量时间在仓库观察了整个事件的处理过程,并开发出该过程所执行活动…

VTK中polydata的属性数据结构表示和用法

vtk中通过vtkDataArray进行数据的存储,通过vtkDataObject进行可视化数据的表达,在vtkDataObject内部有一个vtkFieldData的实例,负责对数据的表达: vtkFieldData存储数据的属性数据,该数据是对拓扑结构和几何结构信息的…

局域网与城域网(练习题)

局域网与城域网 ⭐️⭐️⭐️⭐️ 红色标记为答案⭐️⭐️⭐️⭐️ ⭐️⭐️⭐️ 蓝色标记为要点解析⭐️⭐️⭐️ 1.以下关于VLAN标记的说法中,错误的是()。 A.交换机根据目标地址和VLAN标记进行转发决策 B.进入目的网段时,交换机…

C语言-atoi函数的模拟

模拟术语讲解 首先,需要定义一个标志位变量sign,用于表示转换结果的合法性1。定义一个函数My_atoi,用于实现atoi的功能1。在My_atoi函数中,首先遍历字符串,直到遇到第一个非空格字符1。如果第一个字符不是数字或正负号…

通讯录改造———文件版本

上一篇文章我们详细讲了文件操作,这时候我们就可以把通讯录保存到文件中,这样即使程序退出了,联系人的信息也还是保存着,下一次启动程序时我们就可以把文件中的数据读取到程序中来使用。 保存 首先我们要在退出通讯录之前把联系人…

Spring Boot 介绍

1、SpringBoot 介绍 用通俗的话讲,SpringBoot 在Spring生态基础上发展而来,它的发现不是取代Spring,是为了让人们更容易使用Spring。 2、相关依赖关系 Spring IOC/AOP > Spring > Spring Boot > Spring Cloud 3、 SpringBoot工作原…

R语言,数据类型转换

原文链接:R语言技能 | 不同数据类型的转换 本期教程 写在前面 今天是4月份的第一天,再过2天后再一次迎来清明小假期。木鸡大家是否正常放假呢? 我们在使用R语言做数据分析时,会一直对数据进行不同类型的转换,有时候…

IP地址与子网掩码

1 IP地址 1.1 IPv4与IPv6 1.2 IPv4地址详解 IPv4地址分4段,每段8位,共32位二进制数组成。 1.2.1 地址分类 这32位又被分为网络号和主机号两部分,根据网络号占用位数的不同,又可分为以下几类: A类地址:…