很多老系统、政府门户至今还在用最原始的图片验证码——一段扭曲字符,要求你手动看图输入。没有网格、没有滑块,思路也最直接:把图片交给识别引擎,把文字填回输入框。CaptchaAI 的图片/OCR 接口就是干这件事的,上传图片,几秒后拿到识别文字。下面按截图、提交、轮询、回填四步给出流程,配 Python 与 Node.js 示例。
准备工作
- CaptchaAI API Key:在 captchaai.com 注册后获取
- 验证码图片:图片文件或 base64 编码均可
- 运行环境:Python 3.7+ 或 Node.js 14+
第 1 步:拿到验证码图片
方式一:Selenium 截图
对验证码元素直接截图,不用关心图片的实际 URL:
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get("https://example.com/register")
captcha_el = driver.find_element(By.CSS_SELECTOR, "#captcha-image")
captcha_el.screenshot("captcha.png")
小贴士:CI 或无界面服务器上运行时,给 Chrome 加上
--headless=new参数即可,截图逻辑不用改。
方式二:直接下载图片
图片有独立 URL 时,直接请求下载即可,省掉一次浏览器渲染:
import requests
import base64
img_url = "https://example.com/captcha/generate"
img_data = requests.get(img_url).content
# Save to file
with open("captcha.png", "wb") as f:
f.write(img_data)
# Or convert to base64
img_b64 = base64.b64encode(img_data).decode()
小贴士:能拿到图片直接 URL 时优先用这种方式——不用启动浏览器、不用等页面渲染,批量处理时差距会很明显。
第 2 步:把图片提交给 CaptchaAI
方式 A:文件上传(Python)
import requests
import time
API_KEY = "YOUR_API_KEY"
with open("captcha.png", "rb") as f:
response = requests.post("https://ocr.captchaai.com/in.php",
data={"key": API_KEY, "method": "post", "json": 1},
files={"file": ("captcha.png", f, "image/png")}
)
data = response.json()
task_id = data["request"]
print(f"Task: {task_id}")
方式 B:Base64(Python)
不想处理 multipart 上传,转成 base64 字符串提交也可以:
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "base64",
"body": img_b64,
"json": 1
})
task_id = response.json()["request"]
Node.js(base64)
const axios = require('axios');
const fs = require('fs');
async function submitImageCaptcha(imagePath) {
const imageB64 = fs.readFileSync(imagePath).toString('base64');
const { data } = await axios.post('https://ocr.captchaai.com/in.php', null, {
params: {
key: 'YOUR_API_KEY',
method: 'base64',
body: imageB64,
json: 1
}
});
return data.request;
}
小贴士:base64 编码后体积会比原图大约 33%。图片超过几百 KB 时,优先用方式 A 的文件上传,减少请求体积和序列化开销。
第 3 步:轮询识别结果
提交后不会立刻拿到文字,需要每隔几秒轮询一次 res.php:
def get_text_solution(task_id):
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
return result["request"] # The recognized text
if result.get("request") != "CAPCHA_NOT_READY":
raise Exception(f"Error: {result['request']}")
raise Exception("Timeout")
text = get_text_solution(task_id)
print(f"CAPTCHA text: {text}")
async function getSolution(taskId) {
for (let i = 0; i < 30; i++) {
await new Promise(r => setTimeout(r, 5000));
const { data } = await axios.get('https://ocr.captchaai.com/res.php', {
params: { key: 'YOUR_API_KEY', action: 'get', id: taskId, json: 1 }
});
if (data.status === 1) return data.request;
if (data.request !== 'CAPCHA_NOT_READY') throw new Error(data.request);
}
throw new Error('Timeout');
}
图片验证码通常 5–15 秒出结果,比交互式挑战快很多。识别错了可以用
action=reportbad上报,系统核实后通常会退还这次消耗。
第 4 步:把文字回填到表单
拿到识别结果后,直接把文字填进验证码输入框,再提交表单:
# Type the solved text into the CAPTCHA input
captcha_input = driver.find_element(By.CSS_SELECTOR, "#captcha-input")
captcha_input.clear()
captcha_input.send_keys(text)
# Submit the form
driver.find_element(By.CSS_SELECTOR, "form").submit()
可选参数:让识别更准
图片验证码的字符集往往有规律——只有数字、固定长度、区分大小写。提前告诉 CaptchaAI 这些规律,能减少误识别:
| 参数 | 取值 | 作用 |
|---|---|---|
numeric |
1 = 仅数字,2 = 仅字母 |
限制字符集 |
min_len |
整数 | 最小文本长度 |
max_len |
整数 | 最大文本长度 |
language |
0 = 任意、1 = 西里尔字母、2 = 拉丁字母 |
字符语言 |
calc |
1 |
验证码是一个数学表达式 |
phrase |
1 |
验证码文本包含空格 |
regsense |
1 |
区分大小写 |
常见组合速查:
- 4 位纯数字验证码:
numeric=1、min_len=4、max_len=4 - 6 位英文字母验证码:
numeric=2、min_len=6、max_len=6 - 含空格的短语验证码:
phrase=1
response = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "base64",
"body": img_b64,
"numeric": 1, # Digits only
"min_len": 4, # At least 4 characters
"max_len": 6, # At most 6 characters
"json": 1
})
完整 Python 示例
把前面四步串联起来,完整脚本如下:
import requests
import time
import base64
from selenium import webdriver
from selenium.webdriver.common.by import By
API_KEY = "YOUR_API_KEY"
# 1. Get the page and capture captcha
driver = webdriver.Chrome()
driver.get("https://example.com/register")
captcha_el = driver.find_element(By.CSS_SELECTOR, "#captcha-image")
captcha_el.screenshot("captcha.png")
# 2. Submit to CaptchaAI
with open("captcha.png", "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY, "method": "base64", "body": img_b64, "json": 1
}).json()
task_id = resp["request"]
# 3. Get solution
for _ in range(30):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY, "action": "get", "id": task_id, "json": 1
}).json()
if result.get("status") == 1:
text = result["request"]
break
# 4. Type and submit
driver.find_element(By.CSS_SELECTOR, "#captcha-input").send_keys(text)
driver.find_element(By.CSS_SELECTOR, "form").submit()
print(f"Solved: {text}")
driver.quit()
想要现成的完整项目?
包含环境变量管理、重试策略和错误处理的可运行版本在这里:
常见问题
Selenium 截图验证码时,截到的图片是空白或裁剪不全,怎么办?
多半是截图时机太早,页面还没渲染完。截图前用 WebDriverWait 等待元素可见,再 .screenshot(),能明显减少空白截图。
数学验证码(比如“3 + 7”)能自动识别吗?
可以。把 calc 设为 1,CaptchaAI 会直接算出结果返回数字(“3 + 7”返回“10”),不用你自己解析。
国内很多网站已经换成滑块或 GeeTest(极验),图片验证码是不是过时了?
消费级新系统里确实少见了,但政务、教务、企业旧后台仍在大量使用。CaptchaAI 同时支持 GeeTest v3 滑块识别,两条接口可搭配用。
识别结果大小写不对,导致登录一直失败,怎么处理?
默认结果可能是小写,如果目标站点区分大小写,直接提交就会一直失败。两种处理方式:
- 目标站点区分大小写:把
regsense设为1,让识别结果保留原始大小写 - 目标站点不区分大小写:不用改,保持默认即可
相关指南
- 图片验证码识别 (OCR) 的工作原理
- 常见 OCR 验证码错误与修复方法
- 什么是 Solve Media 验证码