验证码识别
版权声明:本博客来自路飞学城Python全栈开发培训课件,仅用于学习之用,严禁用于商业用途。
欢迎访问路飞学城官网:https://www.luffycity.com/
本节重点
- 超级鹰验证码服务平台使用
1. 引子
1.1 what is 验证码?
验证码是一种区分用户是计算机还是人的公共全自动程序。验证码可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。
1.2 验证码和爬虫的爱恨情仇
有些时候,我们想要去爬取一些基于某些用户的用户信息,比如爬取张三新浪微博的博文和好友数量……那么这些时候,我们就需要使用爬虫进行某些平台的模拟登陆,登陆成功后爬取该用户的相关用户信息。模拟登陆的过程中,往往会出现验证码的阻挠,并且我们还不可以不处理验证码,否则是不可能实现模拟登陆的。因此,接下来我们就一起来看一下,如何处理或者识别验证码。
1.3 常见验证码的种类
图像验证码:
这种验证码出现的最早,现在也很常见,一般是四位字母或者数字组成的,例如中国知网的注册页面就有类似的验证码,链接为:http://my.cnki.net/elibregister/commonRegister.aspx,页面如图所示:
极验滑动验证码:
极验验证码其官网为:http://www.geetest.com/,它是一个专注于提供验证安全的系统,主要验证方式是拖动滑块拼合图像,若图像完全拼合,则验证成功,即可以成功提交表单,否则需要重新验证,样例如图所示:
点触验证码:
除了极验其实还有另一种常见的且应用广泛的验证码,比较有代表性的就是点触验证码。 可能你对这个名字比较陌生,但是肯定见过类似的验证码,比如 12306,这就是一种典型的点触验证码,如图所示:
我们需要直接点击图中符合要求的图,如果所有答案均正确才会验证成功,如果有一个答案错误,验证就会失败,这种验证码就可以称之为点触验证码。
2. 超级鹰验证码服务平台使用
2.1 平台简介
超级鹰验证码服务平台官网为:https://www.chaojiying.com。 其提供的服务种类非常广泛,可识别的验证码类型非常多,下面是此平台提供的一些服务:
- 英文数字,提供最多 20 位英文数字的混合识别
- 中文汉字,提供最多 7 个汉字的识别
- 纯英文,提供最多 12 位的英文的识别
- 纯数字,提供最多 11 位的数字的识别
- 任意特殊字符,提供不定长汉字英文数字、拼音首字母、计算题、成语混合、 集装箱号等字符的识别
- 坐标选择识别,如复杂计算题、选择题四选一、问答题、点击相同的字、物品、动物等返回多个坐标的识别
具体如有变动以官网为准。
2.2 准备工作
注册账号
在开始之前,我们需要先注册一个超级鹰账号并申请一个软件 ID,注册页面链接为:https://www.chaojiying.com/user/reg/,注册完成之后还需要在后台开发商中心添加一个软件 ID,最后一件事就是充值一些题分,充值多少可以根据价格和识别量自行决定。
获取 API
做好上面的准备工作之后我们就可以开始用程序来对接验证码的识别了。 首先我们可以到官方网站下载对应的 Python API,链接为:https://www.chaojiying.com/api-14.html,但是此 API 是 Python2 版本的,是用 Requests 库来实现的,我们可以简单更改几个地方即可将其修改为 Python3 版本。 修改之后的 API 如下:
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 = {
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
}
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 类,其构造函数接收三个参数,分别是超级鹰的用户名、密码以及软件 ID,保存好以备使用。 接下来是最重要的一个方法叫做 post_pic (),这里需要传入图片对象和验证码的代号,该方法会将图片对象和相关信息发给超级鹰的后台进行识别,然后将识别成功的 Json 返回回来。 另一个方法叫做 report_error (),这个是发生错误的时候的回调,如果验证码识别错误,调用此方法会返还相应的题分。
2.3 图像验证码验识别
需求:
识别古诗文网的验证码,网址为https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx
实例:
import requests
from lxml import etree
from chaojiying import Chaojiying_Client
# 封装识别验证码图片的函数
def getCodeText(imgPath,codeType):
# 普通用户用户名
username = '您的超级鹰用户名'
# 普通用户密码
password = '您的超级鹰密码'
# 软件ID,开发者分成必要参数。登录开发者后台【我的软件】获得!
soft_id = 您的超级鹰软件id
# 图片文件:即将被识别的验证码图片的路径
filename = imgPath
# 验证码类型,# 例:1004表示4位字母数字,不同类型收费不同。请准确填写,否则影响识别率。
# 在此查询所有类型 http://www.yundama.com/price.html
codetype = codeType
result = None
# 检查
if (username == 'username'):
print('请设置好相关参数再测试')
else:
# 初始化
chaojiying = Chaojiying_Client(username, password, soft_id)
im = open(filename, 'rb').read()
# 开始识别,图片路径,验证码类型ID,超时时间(秒),识别结果
result = chaojiying.PostPic(im, codetype)
print(result)
pic_str = result['pic_str']
return pic_str
# 将验证码图片下载到本地
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36'
}
url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
page_text = requests.get(url=url,headers=headers).text
# 解析验证码图片img中src属性值
tree = etree.HTML(page_text)
code_img_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0]
print(code_img_src)
img_data = requests.get(url=code_img_src,headers=headers).content
# 将验证码图片保存到了本地
with open('./code.jpg','wb') as fp:
fp.write(img_data)
# 调用打码平台的示例程序进行验证码图片数据识别
code_text = getCodeText('code.jpg',1004)
print('识别结果为:',code_text)
2.4 其他
超级鹰处理可以识别简单的图像验证码外,还可以识别点触验证码等其他多种验证码,因为点触验证码涉及selenium模拟登陆操作,后期再说。
更多验证码识别方法,请参考:https://cuiqingcai.com/7035.html