服务地址: https://y.xbjs.cn https://v.xbjs.cn
Swagger 在线调试: https://y.xbjs.cn/docs
官方帮助页: https://y.xbjs.cn/help.html
镜像: crosscc/ddddocr-fastapi
本镜像基于 ddddocr 封装,FastAPI 提供 HTTP 接口,包含:验证码识别、滑块匹配、目标检测。
multipart/form-data:文件 / base64 / 远程图片链接application/json:JSON Body 传入 base64png_fix:修复带透明通道 PNGprobability:布尔开关,开启后返回每个字符置信度;开启时 charsets 必填模型只负责图像推理;表单填充、重试、登录逻辑、失败判定属于上层业务,不属于接口能力。
不适合:滑块点选、旋转倒立、算术题、多行中文。
容器内部端口固定:8000,宿主机端口可自定义。官方示例映射宿主机 9898。
# 官方示例(宿主机 9898 → 容器 8000) docker run -d -p 9898:8000 crosscc/ddddocr-fastapi # 如果你想用宿主机 8000,改为 docker run -d -p 8000:8000 crosscc/ddddocr-fastapi
| 路径 | 请求方式 | 用途 |
|---|---|---|
| /ocr | POST | 验证码文字识别(核心) |
| /slide_match | POST | 滑块缺口匹配,返回缺口坐标 |
| /detection | POST | 目标检测,返回框选坐标 |
| /docs | GET | Swagger UI 在线调试 |
| /redoc | GET | Redoc 静态文档 |
请求地址: https://y.xbjs.cn/ocr
Content-Type:multipart/form-data,三选一必填
| 字段 | 类型 | 说明 |
|---|---|---|
| file | file | 图片二进制文件,推荐;png/jpg/jpeg/webp/bmp |
| image | string | base64,不带 data:image/xxx;base64, 前缀 |
| imgurl | string | 公网可访问图片链接,服务端拉取识别 |
Content-Type:application/json,仅支持 image(base64),不支持 file、imgurl
{
"image": "base64字符串(无前缀)",
"charsets": "4",
"probability": false,
"png_fix": false
}
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
| charsets | string | 6 | 字符集编号,见对照表;probability=true 时本参数为必填 |
| probability | boolean | false | 是否返回每个字符置信度;form 提交可传字符串 "true"/"false",接口自动兼容 |
| png_fix | boolean | false | 透明通道修复,PNG 识别异常时开启 |
强制规则:probability = true → charsets 必须显式传入,否则报错。
| 编号 | 字符范围 | 说明 |
|---|---|---|
| 0 | 纯数字 0–9 | 仅数字 |
| 1 | 纯小写字母 a–z | 仅小写英文 |
| 2 | 纯大写字母 A–Z | 仅大写英文 |
| 3 | 小写 a–z + 大写 A–Z | 大小写字母混合,不含数字 |
| 4 | 小写 a–z + 数字 0–9 | 小写字母 + 数字(最常用验证码) |
| 5 | 大写 A–Z + 数字 0–9 | 大写字母 + 数字 |
| 6 | 小写 + 大写 + 数字 | 默认值,字母数字全部 |
| 7 | 默认库(6 + 额外符号) | 包含符号,识别范围最大 |
固定站点验证码格式时优先锁定 charsets,缩小候选集,速度和准确率更高。
HTTP 状态码统一为 200,业务状态看返回体内 code。
{
"code": 200,
"message": "Success",
"data": "a7s2"
}
{
"code": 200,
"message": "Success",
"data": "a7s2",
"probability": [
{"char":"a","prob":0.98},
{"char":"7","prob":0.95},
{"char":"s","prob":0.91},
{"char":"2","prob":0.93}
]
}
{
"code": 400,
"message": "Either file, image (base64) or imgurl must be provided",
"data": null
}
| code | 说明 |
|---|---|
| 200 | 识别成功 |
| 400 | 参数错误、图片损坏、base64 非法、缺少必填项(如 probability=true 但无 charsets) |
| 500 | 服务内部异常、内存不足、推理失败 |
① form-data 文件上传(推荐)
curl -X POST \ -F "file=@captcha.png" \ -F "charsets=4" \ -F "probability=false" \ -F "png_fix=false" \ https://y.xbjs.cn/ocr
② JSON base64
curl -X POST https://y.xbjs.cn/ocr \
-H "Content-Type: application/json" \
-d '{
"image": "base64字符串(无前缀)",
"charsets": "4",
"probability": false
}'
③ 开启 probability(必须带 charsets)
curl -X POST https://y.xbjs.cn/ocr \
-H "Content-Type: application/json" \
-d '{
"image": "base64字符串(无前缀)",
"charsets": "4",
"probability": true
}'
import requests, base64
API_URL = "https://y.xbjs.cn/ocr"
def ocr_b64(b64_str: str, charsets: str, prob: bool = False):
payload = {
"image": b64_str,
"charsets": charsets,
"probability": prob,
"png_fix": False
}
resp = requests.post(API_URL, json=payload)
ret = resp.json()
if ret["code"] == 200:
return ret
raise Exception(ret["message"])
if __name__ == "__main__":
with open("captcha.png", "rb") as f:
b64 = base64.b64encode(f.read()).decode()
res = ocr_b64(b64, charsets="4", prob=False)
print(res["data"])
很多验证码链接 GET 即刷新,不要直接 fetch(img.src);用 Canvas 读取页面已渲染图片。
// Canvas 导出 base64,去掉前缀
function getImgBase64(imgEl) {
return new Promise(resolve => {
const canvas = document.createElement("canvas");
canvas.width = imgEl.naturalWidth;
canvas.height = imgEl.naturalHeight;
const ctx = canvas.getContext("2d");
ctx.drawImage(imgEl, 0, 0);
const full = canvas.toDataURL("image/png");
resolve(full.split(",")[1]);
})
}
async function recognize(b64, charsets = "4", probability = false) {
const payload = {
image: b64,
charsets: charsets,
probability: probability,
png_fix: false
};
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: "POST",
url: "https://y.xbjs.cn/ocr",
headers: { "Content-Type": "application/json" },
data: JSON.stringify(payload),
onload: res => {
const json = JSON.parse(res.responseText);
if (json.code === 200) resolve(json);
else reject(json.message);
},
onerror: e => reject(e)
})
})
}
脚本头部必须:// @grant GM_xmlhttpRequest
data:image/png;base64, 前缀png_fix: true对齐 crosscc/ddddocr-fastapi 官方帮助页