Python3爬虫实战:利用超级鹰API识别点触验证码
本文详解如何使用Python3结合Selenium与超级鹰API识别点触验证码。针对OCR技术处理变形文字和复杂背景效果不佳的问题,介绍通过在线打码平台获取坐标的方案。内容涵盖账号注册、API封装、图片截取、坐标解析及模拟点击全流程,适用于12306等常见点触场景。
点触验证码识别概述
前文已介绍极验验证码的识别方法,除此之外,还有一种应用广泛且极具代表性的验证码类型,即点触验证码。
或许你对“点触验证码”这一术语感到陌生,但实际生活中你一定接触过类似机制,例如12306网站的登录验证,其典型界面如下图所示:

此类验证码要求用户直接点击图中符合特定描述的图像区域。只有当所有指定目标均被正确选中时,验证才会通过;若任一目标点击错误或遗漏,验证即告失败。这种交互形式的验证码统称为点触验证码。
此外,市场上存在专门提供点触验证码服务的平台,如TouClick,其官方网站为:https://www.touclick.com/。本节将以此平台为例,详细讲解此类验证码的识别流程。
1. 本节目标
本节的旨在通过编程手段,自动识别并成功通过点触验证码的验证环节。
2. 准备工作
本次实践将使用Python的Selenium库,配合Chrome浏览器进行自动化操作。在开始之前,请确保已正确安装Selenium库、Chrome浏览器,并配置好对应的ChromeDriver驱动。具体的安装与配置流程可参考本书第一章的相关说明。
3. 了解点触验证码
TouClick官方网站展示的验证码样式如图8-19所示:

该样式与12306站点有相似之处,区别在于本次需要点击图片中的文字而非单纯图形。此外,市面上还存在各种形态各异的点触验证码,尽管交互细节略有差异,但其核心原理基本一致。
接下来,我们将统一阐述此类点触验证码的识别逻辑与实现步骤。
识别难点与思路分析
4. 识别思路
若完全依赖传统的图像识别技术来处理此类验证码,难度极高。
以12306为例,其识别难点主要体现在两个方面。第一点是文字识别,如图8-20所示:

例如要求点击图中所有的“漏斗”,但“漏斗”二字往往经过变形、缩放及模糊处理。若强行使用前文提到的OCR技术,识别精度将大幅降低,甚至无法得出任何结果。第二点是图像识别,虽然可借助各类识图接口将图像转化为文字,但实测表明,其正确匹配率极低,常出现匹配错误或无结果的情况。加之图片本身清晰度不足,识别难度进一步增加。更关键的是,系统要求同时从八张图片中准确识别出多个目标,且所有答案必须完全匹配才能通过验证。综合考量,纯技术识别方案基本不可行。
再看TouClick平台的案例,如图所示:

我们需要从图片中识别出“植株”二字,但图片背景通常包含干扰元素,导致OCR识别几乎无法成功。有人或许会问,直接识别白色文字是否可行?然而,若更换一张验证码,如图8-22所示:

此时文字颜色变为蓝色,且带有白色阴影,识别难度随之显著增加。
那么此类验证码是否无解?答案是否定的。解决之道在于“人工”辅助。
依靠人工解决?那程序还有何用?请勿着急,此处所言的“人”并非指开发者亲自操作,而是指互联网上存在的众多验证码识别服务平台。这些平台提供7×24小时的自动化识别服务,图片上传后数秒即可返回结果,准确率可达90%以上。虽然这需要付费购买服务(毕竟平台需盈利),但成本极低,识别一个验证码仅需几分钱。
在此,个人推荐一个较为可靠的平台:超级鹰。
该平台提供的服务种类广泛,支持的验证码类型繁多,其中便包括此类点触验证码。
此外,超级鹰平台同样支持简单的图形验证码识别。若OCR识别存在困难,亦可采用本节相同的方法,借助此平台进行识别。以下是该平台提供的一些主要服务类型:
英文数字混合识别:支持最多20位英文与数字的组合。
中文汉字识别:支持最多7个汉字的识别。
纯英文识别:支持最多12位英文字母的识别。
纯数字识别:支持最多11位数字的识别。
任意特殊字符识别:支持不定长的汉字、英文、数字、拼音首字母、计算题、成语混合、集装箱号等字符的识别。
坐标选择识别:适用于复杂计算题、四选一选择题、问答题、点击相同字/物品/动物等场景,返回多个坐标点。
本节需要解决的问题属于最后一类,即坐标多选识别。具体操作是将验证码图片提交至平台,平台返回图片中目标位置的坐标,随后我们解析这些坐标并模拟点击即可。
原理十分简单,下面我们将通过实际代码进行演示。
超级鹰平台注册与配置
5. 注册账号
在开始编码前,我们需要先注册一个超级鹰账号,并申请一个软件ID。注册页面链接为:https://www.chaojiying.com/user/reg/。注册完成后,还需在后台的“开发商中心”添加一个软件ID。最后一步是充值题分,充值金额可根据识别频率和价格自行决定。
Python API封装与对接
6. 获取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(),这是用于处理识别错误的回调函数。若验证码识别错误,调用此方法可返还相应的题分。
随后,我们以TouClick官网为例演示点触验证码的识别过程,链接为:http://admin.touclick.com/。若未注册账号,请先完成注册。
Selenium自动化流程实现
7. 初始化
首先,我们需要初始化一些必要变量,如WebDriver实例、Chaojiying对象等,具体代码实现如下:
EMAIL = 'cqc@cuiqingcai.com'
PASSWORD = ''
# 超级鹰用户名、密码、软件ID、验证码类型
CHAOJIYING_USERNAME = 'Germey'
CHAOJIYING_PASSWORD = ''
CHAOJIYING_SOFT_ID = 893590
CHAOJIYING_KIND = 9102
class CrackTouClick():
def __init__(self):
self.url = 'http://admin.touclick.com/login.html'
self.browser = webdriver.Chrome()
self.wait = WebDriverWait(self.browser, 20)
self.email = EMAIL
self.password = PASSWORD
self.chaojiying = Chaojiying(CHAOJIYING_USERNAME, CHAOJIYING_PASSWORD, CHAOJIYING_SOFT_ID)
请注意,其中的账号和密码需替换为你自己的真实信息。
8. 获取验证码
第一步是完善相关表单,并模拟点击以呼出验证码。此步骤较为简单,代码实现如下:
def open(self):
"""
打开网页输入用户名密码
:return: None
"""
self.browser.get(self.url)
email = self.wait.until(EC.presence_of_element_located((By.ID, 'email')))
password = self.wait.until(EC.presence_of_element_located((By.ID, 'password')))
email.send_keys(self.email)
password.send_keys(self.password)
def get_touclick_button(self):
"""
获取初始验证按钮
:return:
"""
button = self.wait.until(EC.element_to_be_clickable((By.CLASS_NAME, 'touclick-hod-wrap')))
return button
在此,open()方法负责填写表单信息,get_touclick_button()方法用于获取验证码按钮,随后触发点击操作即可。
接下来,我们需要像处理上一节极验验证码一样,首先获取验证码图片的位置和尺寸,然后从网页截图中截取相应的验证码区域。代码实现如下:
def get_touclick_element(self):
"""
获取验证图片对象
:return: 图片对象
"""
element = self.wait.until(EC.presence_of_element_located((By.CLASS_NAME, 'touclick-pub-content')))
return element
def get_position(self):
"""
获取验证码位置
:return: 验证码位置元组
"""
element = self.get_touclick_element()
time.sleep(2)
location = element.location
size = element.size
top, bottom, left, right = location['y'], location['y'] + size['height'], location['x'], location['x'] + size[
'width']
return (top, bottom, left, right)
def get_screenshot(self):
"""
获取网页截图
:return: 截图对象
"""
screenshot = self.browser.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
return screenshot
def get_touclick_image(self, name='captcha.png'):
"""
获取验证码图片
:return: 图片对象
"""
top, bottom, left, right = self.get_position()
print('验证码位置', top, bottom, left, right)
screenshot = self.get_screenshot()
captcha = screenshot.crop((left, top, right, bottom))
return captcha
其中,get_touclick_image()方法负责从网页截图中截取验证码图片,验证码的相对位置坐标由get_position()方法返回。最终,我们得到一个Image对象。
坐标解析与模拟点击
9. 识别验证码
随后,调用Chaojiying对象的post_pic()方法,将图片发送至超级鹰后台。此处发送的图像数据为字节流格式,代码实现如下:
image = self.get_touclick_image()
bytes_array = BytesIO()
image.save(bytes_array, format='PNG')
# 识别验证码
result = self.chaojiying.post_pic(bytes_array.getvalue(), CHAOJIYING_KIND)
print(result)
运行上述代码后,result变量将存储超级鹰后台的识别结果。由于后台可能涉及人工辅助识别,运行可能需要等待数秒。
返回的结果为JSON格式,若识别成功,典型的返回结果如下所示:
{'err_no': 0, 'err_str': 'OK', 'pic_id': '6002001380949200001', 'pic_str': '132,127|56,77', 'md5': '1f8e1d4bef8b
11484cb1f1f34299865b'}
其中,pic_str字段包含识别出的文字坐标,以字符串形式返回,各坐标之间以“|”分隔。接下来,我们只需解析该字符串,并模拟点击对应位置即可,代码实现如下:
def get_points(self, captcha_result):
"""
解析识别结果
:param captcha_result: 识别结果
:return: 转化后的结果
"""
groups = captcha_result.get('pic_str').split('|')
locations = [[int(number) for number in group.split(',')] for group in groups]
return locations
def touch_click_words(self, locations):
"""
点击验证图片
:param locations: 点击位置
:return: None
"""
for location in locations:
print(location)
ActionChains(self.browser).move_to_element_with_offset(self.get_touclick_element(), location[0],
location[1]).click().perform()
time.sleep(1)
在此,get_points()方法将识别结果转换为列表格式。最后,touch_click_words()方法通过调用move_to_element_with_offset()方法,依次传入解析后的坐标,执行点击操作。
至此,我们便模拟完成了坐标的点选操作,运行效果如下图所示:

最后一步是点击提交验证按钮,等待验证通过,再点击登录按钮即可完成登录。后续实现细节在此不再赘述。
通过借助在线验证码平台,我们成功完成了点触验证码的识别。该方法具有通用性,同样适用于12306等其他平台的验证码识别,原理完全一致。
10. 本节代码
本节的完整代码地址为:https://github.com/Python3WebSpider/CrackTouClick。
11. 结语
本节通过在线打码平台辅助完成了验证码识别。这种方法极为强大,几乎可应对任意类型的验证码。若遇到技术难题,借助打码平台无疑是一个极佳的选择。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









