最近在开发一个自动化测试项目时,遇到了hCaptcha验证码的识别难题。经过多方调研,发现了一个可靠的hCaptcha图像识别API服务。下面我将详细介绍整个对接过程,包括申请流程、使用方法和实战技巧。
hCaptcha是目前互联网上广泛使用的一种验证码系统,它通过要求用户识别特定图像来区分人类和机器人。相比传统验证码,hCaptcha更难被自动化破解,这也给我们的自动化测试带来了挑战。
首先需要访问API提供商的平台页面。在浏览器中输入以下地址:
code复制https://platform.acedata.cloud/documents/c9a5cc2f-e410-425f-857a-f8700205da6c
进入页面后,你会看到详细的API文档和"Acquire"按钮。点击该按钮开始申请流程:
提示:首次申请的用户会获得一定的免费额度,建议先用这些免费额度进行测试和验证。
成功申请服务后,你可以在个人中心找到专属的API密钥。这个密钥是调用API的凭证,需要妥善保管。密钥通常以"Bearer"开头,格式如下:
code复制Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
这个API的核心功能是分析hCaptcha验证码图像,并返回需要点击的目标位置坐标。其工作流程如下:
调用API时需要准备以下关键参数:
queries参数:
question参数:
headers参数:
首先需要找到一个包含hCaptcha的测试页面,例如:
code复制https://democaptcha.com/demo-form-eng/hcaptcha.html
操作步骤:
注意:截图时建议使用工具去除浏览器边框等无关内容,只保留验证码本身。
获取验证码截图后,需要进行以下处理:
Python示例代码:
python复制import base64
from PIL import Image
from io import BytesIO
def image_to_base64(image_path):
with Image.open(image_path) as img:
# 压缩图像
img.thumbnail((500, 500))
buffered = BytesIO()
img.save(buffered, format="PNG")
return base64.b64encode(buffered.getvalue()).decode('utf-8')
准备好图像和问题文本后,可以构造API请求了。以下是Python示例:
python复制import requests
api_url = "https://api.acedata.cloud/captcha/recognition/hcaptcha"
api_key = "你的API密钥" # 替换为实际密钥
headers = {
"accept": "application/json",
"authorization": f"Bearer {api_key}",
"content-type": "application/json"
}
payload = {
"question": "Please click on the UNIQUE object among the others.",
"queries": [image_to_base64("captcha.png")] # 使用上一步的函数
}
response = requests.post(api_url, json=payload, headers=headers)
print(response.json())
成功的API调用会返回类似如下的JSON响应:
json复制{
"solution": {
"label": "Please click on the UNIQUE object among the others",
"box": ["360", "276"],
"confidences": 0.6354503631591797
}
}
关键字段说明:
box: 目标位置的坐标[x, y]confidences: 识别置信度(0-1)label: 识别的问题文本API返回的坐标基于以下坐标系:
例如返回坐标[360, 276]表示:
根据返回坐标实现点击的Python示例:
python复制import pyautogui
def click_position(x, y):
# 获取验证码在屏幕上的位置
captcha_location = pyautogui.locateOnScreen('captcha.png')
if captcha_location:
# 计算绝对坐标
abs_x = captcha_location.left + x
abs_y = captcha_location.bottom - y # 因为坐标系原点不同
pyautogui.click(abs_x, abs_y)
else:
print("无法定位验证码位置")
API可能返回的错误代码及处理方法:
| 错误代码 | 原因 | 解决方案 |
|---|---|---|
| 400 token_mismatched | 参数缺失或无效 | 检查请求参数 |
| 401 invalid_token | API密钥无效 | 检查并更新API密钥 |
| 429 too_many_requests | 请求频率过高 | 降低调用频率或升级套餐 |
| 500 api_error | 服务器内部错误 | 联系技术支持 |
图像预处理:
重试机制:
缓存机制:
在实际项目中,我总结了以下几点经验:
图像质量至关重要:
坐标转换陷阱:
网络延迟考虑:
合规使用:
下面是一个完整的Python实现示例:
python复制import requests
import base64
from PIL import Image
from io import BytesIO
import pyautogui
import time
class HCaptchaSolver:
def __init__(self, api_key):
self.api_url = "https://api.acedata.cloud/captcha/recognition/hcaptcha"
self.api_key = api_key
def image_to_base64(self, image_path):
with Image.open(image_path) as img:
img.thumbnail((500, 500))
buffered = BytesIO()
img.save(buffered, format="PNG")
return base64.b64encode(buffered.getvalue()).decode('utf-8')
def solve_captcha(self, image_path, question):
headers = {
"accept": "application/json",
"authorization": f"Bearer {self.api_key}",
"content-type": "application/json"
}
payload = {
"question": question,
"queries": [self.image_to_base64(image_path)]
}
try:
response = requests.post(self.api_url, json=payload, headers=headers)
result = response.json()
if "solution" in result:
return result["solution"]["box"]
elif "error" in result:
print(f"API错误: {result['error']['message']}")
return None
except Exception as e:
print(f"请求失败: {str(e)}")
return None
def click_captcha(self, image_path, coords):
try:
x, y = map(int, coords)
captcha_location = pyautogui.locateOnScreen(image_path)
if captcha_location:
abs_x = captcha_location.left + x
abs_y = captcha_location.bottom - y
pyautogui.moveTo(abs_x, abs_y, duration=0.5)
pyautogui.click()
return True
return False
except Exception as e:
print(f"点击失败: {str(e)}")
return False
# 使用示例
if __name__ == "__main__":
solver = HCaptchaSolver("你的API密钥")
# 1. 手动截图保存为captcha.png
# 2. 获取问题文本
question = "Please click on the UNIQUE object among the others."
# 3. 调用API解析
coords = solver.solve_captcha("captcha.png", question)
if coords:
print(f"识别结果坐标: {coords}")
# 4. 模拟点击
if solver.click_captcha("captcha.png", coords):
print("验证码点击成功!")
else:
print("点击验证码失败")
else:
print("验证码识别失败")
对于需要处理大量验证码的场景,可以考虑:
可以将验证码识别功能封装成测试框架的插件:
建议建立验证码识别准确率监控:
除了本文介绍的API,还有其他几种处理hCaptcha的方案:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| API识别 | 准确率高,维护成本低 | 有使用成本 | 中小规模自动化 |
| 机器学习模型 | 自主可控,长期成本低 | 开发难度大 | 大规模专业应用 |
| 人工打码平台 | 解决复杂验证码 | 速度慢,成本高 | 特殊验证码 |
| 浏览器自动化 | 无需额外服务 | 易被检测封禁 | 简单测试 |
根据项目需求和规模,选择最适合的方案。对于大多数自动化测试场景,使用专业API是最平衡的选择。