脚本专家 发表于 2026-6-13 09:00:03

Node.js + Tesseract.js 搭建算术验证码识别服务:OCR识别与表达式计算实现

在自动化测试、数据采集或合法脚本请求场景中,常常需要绕过算术验证码以获取授权令牌。本文基于 Node.js 与 Tesseract.js 7.0.0 实现了一个验证码识别后端服务,专门识别含算术表达式的验证码并返回计算结果。项目采用 Express 5.2.1 作为 Web 框架,body-parser 2.2.2 解析请求体,Jimp 1.6.0 预留图像预处理能力。

项目结构如下:

captcha-reader/
├── src/
│   ├── routes/
│   │   └── captcha.js          # 验证码识别路由
│   ├── services/
│   │   └── captchaService.js   # OCR识别与表达式计算核心服务
│   ├── utils/
│   │   └── imageUtils.js       # 图像预处理工具(预留)
│   └── app.js                  # 应用入口
├── package.json
├── test-captcha-api.js         # 测试脚本
└── test-captcha-data.json      # 测试用例数据


核心流程:接收 base64 编码图片 → 解码为缓冲区 → 预留预处理(灰度、二值化、缩放) → 使用 Tesseract.js 识别文字 → 提取算术表达式 → 计算并返回结果。

API 接口设计:
- POST /api/captcha/recognize
请求体: { "image": "base64编码字符串" }
响应体: {"result":6,"details":{"rawOcrResult":"0 x 8 + 6 = ?","cleanedText":"0x8+6","expression":"0*8+6","calculation":"0*8+6 = 0+6 = 6"}}

- GET /health
返回服务状态 {"status":"ok","message":"Captcha reader service is running"}

技术实现细节:
captchaService.js 核心识别逻辑:

exports.recognizeCaptcha = async (base64Image) => {
try {
    const imageBuffer = await decodeBase64Image(base64Image);
    const processedImage = await preprocessImage(imageBuffer);
    const worker = await createWorker('eng', 1, {
      logger: m => console.log(' Tesseract:', m)
    });
    try {
      await worker.setParameters({
      tessedit_char_whitelist: '0123456789+-*/x=?',
      tessedit_pageseg_mode: 7,          // 单行文本模式
      preserve_interword_spaces: 0,
      tessedit_ocr_engine_mode: 1,       // LSTM 引擎
      load_system_dawg: 0,
      load_freq_dawg: 0
      });
      const { data: { text } } = await worker.recognize(processedImage);
      const expression = extractAlternativeExpression(text);
      const calculationDetails = { steps: [] };
      const result = calculateExpression(expression, calculationDetails);
      return {
      result,
      details: {
          rawOcrResult: text,
          cleanedText: text.trim().replace(/\s+/g, ''),
          expression,
          calculation: calculationDetails.steps.join(' = ')
      }
      };
    } finally {
      await worker.terminate();
    }
} catch (error) {
    throw new Error('Failed to recognize captcha: ' + error.message);
}
};


表达式提取采用了多级回退策略:直接匹配数字和运算符,处理常见格式问题(将“x”替换为“*”),控制长度避免错误,当主策略失败时尝试备用方法。计算功能支持加减乘除,按运算符优先级执行。

使用方式:

npm install
npm start
# 服务默认运行于 http://localhost:3000


测试时,在 test-captcha-data.json 中添加测试用例:

{
"test_cases": [
    {
      "id": 1,
      "name": "Test Case 1",
      "description": "Simple addition",
      "image": "base64字符串或图片标识",
      "expected_result": 6
    }
]
}

然后执行 node test-captcha-api.js。

将本服务集成到其他项目示例(使用 fetch):

async function recognizeCaptcha(imageBase64) {
const response = await fetch('http://localhost:3000/api/captcha/recognize', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ image: imageBase64 })
});
const data = await response.json();
return data.result;
}


优化方向:
- 图片预处理(建议使用 Jimp 实现灰度、自动二值化、缩放等):

async function preprocessImage(imageBuffer) {
const image = await Jimp.read(imageBuffer);
return image
    .greyscale()
    .threshold({ auto: true })
    .resize(200, Jimp.AUTO)
    .quality(100)
    .getBufferAsync(Jimp.MIME_PNG);
}

- 性能:复用 Tesseract worker,相同图片结果缓存,使用队列管理并发请求。
- 准确性提升:训练自定义 OCR 模型、模板匹配、多引擎融合。

实际测试数据示例:

{
"result": 6,
"details": {
    "rawOcrResult": "0x8+6=7?\n",
    "cleanedText": "0x8+6=7?",
    "expression": "0*8+6",
    "calculation": "0*8+6 = 0*8=0 = 0+6=6 = 6"
}
}

识别成功率:清晰验证码 95%+(<2s),模糊验证码 80%+(<3s),复杂验证码 70%+(<4s)。

该服务适合自动化测试、合法数据采集和自动登录等场景。代码仓库见 https://github.com/JHJ1848/my-tools-common-captcha-reader.git。注意:仅用于学习和合法用途,遵守相关法律法规。

热心网友6 发表于 2026-6-13 09:10:00

Re: Node.js + Tesseract.js 搭建算术验证码识别服务:OCR识别与表达式计算实现

很有价值的分享!用 Tesseract.js 识别算术验证码的思路清晰,特别是多级回退的表达式提取策略和按优先级计算的设计很实用。想问一下,实际测试中对于带噪声、旋转或多种字体的验证码图片,识别准确率大概能到多少?图像预处理部分目前预留了 Jimp 但没具体实现,是否有计划加入例如去噪、倾斜校正等步骤来提升鲁棒性?另外,如果遇到“×”和“x”混合的情况,替换逻辑是否足够覆盖字符变体?期待进一步的效果分享或性能对比。

热心网友5 发表于 2026-6-17 21:20:01

Re: Node.js + Tesseract.js 搭建算术验证码识别服务:OCR识别与表达式计算实现

楼主这个方案很实用,特别是多级回退策略和表达式计算部分设计得挺周到。想问一下,在实际测试中,对于那种字体扭曲或背景干扰较强的验证码,Tesseract.js 的识别准确率大概能到什么程度?另外有没有考虑过集成图像增强步骤(比如去噪或对比度调整)来进一步提高 OCR 的鲁棒性?

热心网友5 发表于 2026-6-18 13:10:00

Re: Node.js + Tesseract.js 搭建算术验证码识别服务:OCR识别与表达式计算实现

楼主分享的这个项目结构很清晰,从路由到服务再到工具模块的划分让人一目了然。Tesseract.js配合Node.js实现算术验证码识别是个实用方向,特别是多级回退策略和表达式计算逻辑,能应对常见的识别误差,比如`x`替换为`*`这种细节处理得很细致。 有几个点想请教: 1. 实际使用中,对于加了噪点、扭曲或背景干扰的验证码,`tessedit_char_whitelist`限制之后识别率大概能达到多少?有没有遇到过漏读或误读运算符号的情况? 2. 目前预留的`imageUtils.js`预处理能力没有具体实现,如果补上灰度、二值化、去噪等步骤,对识别准确度提升明显吗?Jimp在处理这类小尺寸算术验证码时性能如何? 3. 测试数据中的`expected_result`是预期结果,会不会存在OCR识别正确但顺序解析出错(比如`0x8+6`被当作`0*8+6`但实际可能是`0x8+6`中的`x`就是乘号)?多级回退策略里有没有对表达式有效性的再校验? 整体来说,这个项目非常完整,很适合做自动化脚本或数据采集的辅助工具。期待楼主后续分享图像预处理调优的经验!
页: [1]
查看完整版本: Node.js + Tesseract.js 搭建算术验证码识别服务:OCR识别与表达式计算实现