基于Node.js和Tesseract.js实现验证码识别服务
作者:敬叫唤
项目简介
在现代 web 应用中,验证码是一种常见的安全措施,用于防止自动化脚本的恶意攻击。然而,在某些合法场景下(如自动化测试、数据采集等),我们也需要一种能够自动识别验证码的能力。
本文将介绍一个基于 Node.js 和 Tesseract.js 实现的验证码识别后端服务,该服务专门用于识别包含算术表达式的验证码,并返回计算结果。
项目架构
技术栈
| 技术/库 | 版本 | 用途 |
|---|---|---|
| Node.js | - | 运行环境 |
| Express | 5.2.1 | Web 框架 |
| Tesseract.js | 7.0.0 | OCR 文字识别 |
| Jimp | 1.6.0 | 图像处理(预留) |
| body-parser | 2.2.2 | 请求体解析 |
项目结构
captcha-reader/ ├── src/ │ ├── routes/ │ │ └── captcha.js # 验证码识别路由 │ ├── services/ │ │ └── captchaService.js # 验证码识别服务 │ ├── utils/ │ │ └── imageUtils.js # 图像处理工具 │ └── app.js # 应用入口 ├── package.json # 项目配置和依赖 ├── test-captcha-api.js # API 测试脚本 └── test-captcha-data.json # 测试数据
核心功能
1. 验证码识别流程
验证码识别服务的工作流程如下:
- 接收请求:接收包含 base64 编码图片的 POST 请求
- 图片解码:将 base64 字符串解码为图片缓冲区
- 图片预处理:(预留)对图片进行灰度转换、二值化等处理
- OCR 识别:使用 Tesseract.js 识别图片中的文字
- 表达式提取:从识别结果中提取算术表达式
- 计算结果:计算表达式的值
- 返回结果:返回计算结果及详细识别信息
2. API 接口
识别验证码
- URL:
/api/captcha/recognize - 方法: POST
- 请求体:
{ "image": "base64 编码的图片字符串" } - 响应:
{ "result": 6, "details": { "rawOcrResult": "0 x 8 + 6 = ?", "cleanedText": "0x8+6", "expression": "0*8+6", "calculation": "0*8+6 = 0+6 = 6" } }
健康检查
- URL:
/health - 方法: GET
- 响应:
{ "status": "ok", "message": "Captcha reader service is running" }
技术实现
1. 验证码识别服务
验证码识别服务是整个项目的核心,负责处理图片识别和计算逻辑:
// src/services/captchaService.js 核心代码
/**
* Recognize captcha image and calculate result
* @param {string} base64Image - Base64 encoded captcha image
* @returns {Promise<Object>} Recognition and calculation result
*/
exports.recognizeCaptcha = async (base64Image) => {
try {
// 解码 base64 图片
const imageBuffer = await decodeBase64Image(base64Image);
// 预处理图片
const processedImage = await preprocessImage(imageBuffer);
// 创建 Tesseract worker
const worker = await createWorker('eng', 1, {
logger: m => console.log(' Tesseract:', m)
});
try {
// 配置 Tesseract 识别选项
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 {
// 终止 worker
await worker.terminate();
}
} catch (error) {
throw new Error('Failed to recognize captcha: ' + error.message);
}
};
2. 表达式提取与计算
项目实现了多种表达式提取策略,以应对不同格式的验证码:
- 基本提取:直接匹配数字和运算符
- 替代提取:处理常见的格式问题,如将 “x” 替换为 “*”
- 长度控制:避免过长的错误表达式
- 多级回退:当主要策略失败时尝试其他方法
计算功能支持基本的算术运算(加、减、乘、除),并按照运算符优先级进行计算。
使用指南
1. 安装与运行
安装依赖:
npm install
启动服务:
npm start
服务默认运行在 http://localhost:3000
2. 测试 API
项目包含一个测试脚本,用于验证 API 的功能:
准备测试数据:
在 test-captcha-data.json 文件中添加测试用例:
{
"test_cases": [
{
"id": 1,
"name": "Test Case 1",
"description": "Simple addition",
"image": "test-captcha",
"expected_result": 6
}
]
}
运行测试:
node test-captcha-api.js
3. 集成到其他项目
可以通过 HTTP 请求将此服务集成到其他项目中:
// 示例:使用 Fetch API 调用验证码识别服务
async function recognizeCaptcha(imageBase64) {
try {
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;
} catch (error) {
console.error('Error recognizing captcha:', error);
return null;
}
}
项目优化
1. 图片预处理
当前项目预留了图片预处理功能,可以通过以下方式实现:
// 建议的图片预处理步骤
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);
}
2. 性能优化
- Worker 复用:可以考虑复用 Tesseract worker 以减少创建和销毁的开销
- 缓存:对相同的验证码图片进行缓存,避免重复识别
- 并发处理:使用队列系统处理多个识别请求
3. 准确性提升
- 训练自定义模型:为特定类型的验证码训练专用的 OCR 模型
- 模板匹配:对于固定格式的验证码,使用模板匹配提高准确率
- 多引擎融合:结合多个 OCR 引擎的结果提高准确性
应用场景
- 自动化测试:在自动化测试中识别验证码
- 数据采集:在合法的数据采集中处理验证码
- 脚本请求自动登录:不采用人为干预进行自动识别登录获取token
测试结果

{
"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 |
示例识别结果
日志截图
识别过程日志

总结
本项目实现了一个基于 Node.js 和 Tesseract.js 的验证码识别后端服务,具有以下特点:
- 简单易用:提供清晰的 RESTful API 接口
- 功能完整:支持从图片识别到结果计算的完整流程
- 高度可定制:预留了图片预处理等可扩展点
- 详细信息:返回详细的识别过程信息,便于调试
- 测试友好:包含完整的测试脚本
通过本项目,我们不仅实现了一个实用的验证码识别工具,也学习了如何使用 Tesseract.js 进行 OCR 识别,以及如何构建一个完整的后端服务。
未来,我们可以通过添加更多的图片预处理步骤、训练自定义模型等方式,进一步提高识别准确率和性能,使其在更多场景下发挥作用。
代码仓库
https://github.com/JHJ1848/my-tools-common-captcha-reader.git

注意:本项目仅用于学习和合法用途,请勿用于任何恶意行为。使用验证码识别技术时,请遵守相关法律法规和网站的使用条款。
到此这篇关于基于Node.js和Tesseract.js实现验证码识别服务的文章就介绍到这了,更多相关Node.js和Tesseract.js验证码识别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
