基于Node.js和Tesseract.js實現(xiàn)驗證碼識別服務(wù)
項目簡介
在現(xiàn)代 web 應(yīng)用中,驗證碼是一種常見的安全措施,用于防止自動化腳本的惡意攻擊。然而,在某些合法場景下(如自動化測試、數(shù)據(jù)采集等),我們也需要一種能夠自動識別驗證碼的能力。
本文將介紹一個基于 Node.js 和 Tesseract.js 實現(xiàn)的驗證碼識別后端服務(wù),該服務(wù)專門用于識別包含算術(shù)表達式的驗證碼,并返回計算結(jié)果。
項目架構(gòu)
技術(shù)棧
| 技術(shù)/庫 | 版本 | 用途 |
|---|---|---|
| Node.js | - | 運行環(huán)境 |
| Express | 5.2.1 | Web 框架 |
| Tesseract.js | 7.0.0 | OCR 文字識別 |
| Jimp | 1.6.0 | 圖像處理(預(yù)留) |
| body-parser | 2.2.2 | 請求體解析 |
項目結(jié)構(gòu)
captcha-reader/ ├── src/ │ ├── routes/ │ │ └── captcha.js # 驗證碼識別路由 │ ├── services/ │ │ └── captchaService.js # 驗證碼識別服務(wù) │ ├── utils/ │ │ └── imageUtils.js # 圖像處理工具 │ └── app.js # 應(yīng)用入口 ├── package.json # 項目配置和依賴 ├── test-captcha-api.js # API 測試腳本 └── test-captcha-data.json # 測試數(shù)據(jù)
核心功能
1. 驗證碼識別流程
驗證碼識別服務(wù)的工作流程如下:
- 接收請求:接收包含 base64 編碼圖片的 POST 請求
- 圖片解碼:將 base64 字符串解碼為圖片緩沖區(qū)
- 圖片預(yù)處理:(預(yù)留)對圖片進行灰度轉(zhuǎn)換、二值化等處理
- OCR 識別:使用 Tesseract.js 識別圖片中的文字
- 表達式提取:從識別結(jié)果中提取算術(shù)表達式
- 計算結(jié)果:計算表達式的值
- 返回結(jié)果:返回計算結(jié)果及詳細識別信息
2. API 接口
識別驗證碼
- URL:
/api/captcha/recognize - 方法: POST
- 請求體:
{ "image": "base64 編碼的圖片字符串" } - 響應(yīng):
{ "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
- 響應(yīng):
{ "status": "ok", "message": "Captcha reader service is running" }
技術(shù)實現(xiàn)
1. 驗證碼識別服務(wù)
驗證碼識別服務(wù)是整個項目的核心,負責(zé)處理圖片識別和計算邏輯:
// 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);
// 預(yù)處理圖片
const processedImage = await preprocessImage(imageBuffer);
// 創(chuàng)建 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);
// 計算結(jié)果
const calculationDetails = { steps: [] };
const result = calculateExpression(expression, calculationDetails);
// 返回結(jié)果
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. 表達式提取與計算
項目實現(xiàn)了多種表達式提取策略,以應(yīng)對不同格式的驗證碼:
- 基本提取:直接匹配數(shù)字和運算符
- 替代提取:處理常見的格式問題,如將 “x” 替換為 “*”
- 長度控制:避免過長的錯誤表達式
- 多級回退:當(dāng)主要策略失敗時嘗試其他方法
計算功能支持基本的算術(shù)運算(加、減、乘、除),并按照運算符優(yōu)先級進行計算。
使用指南
1. 安裝與運行
安裝依賴:
npm install
啟動服務(wù):
npm start
服務(wù)默認(rèn)運行在 http://localhost:3000
2. 測試 API
項目包含一個測試腳本,用于驗證 API 的功能:
準(zhǔn)備測試數(shù)據(jù):
在 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 請求將此服務(wù)集成到其他項目中:
// 示例:使用 Fetch API 調(diào)用驗證碼識別服務(wù)
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;
}
}
項目優(yōu)化
1. 圖片預(yù)處理
當(dāng)前項目預(yù)留了圖片預(yù)處理功能,可以通過以下方式實現(xiàn):
// 建議的圖片預(yù)處理步驟
async function preprocessImage(imageBuffer) {
const image = await Jimp.read(imageBuffer);
return image
.greyscale() // 轉(zhuǎn)換為灰度圖
.threshold({ auto: true }) // 自動二值化
.resize(200, Jimp.AUTO) // 放大圖片
.quality(100) // 提高質(zhì)量
.getBufferAsync(Jimp.MIME_PNG);
}
2. 性能優(yōu)化
- Worker 復(fù)用:可以考慮復(fù)用 Tesseract worker 以減少創(chuàng)建和銷毀的開銷
- 緩存:對相同的驗證碼圖片進行緩存,避免重復(fù)識別
- 并發(fā)處理:使用隊列系統(tǒng)處理多個識別請求
3. 準(zhǔn)確性提升
- 訓(xùn)練自定義模型:為特定類型的驗證碼訓(xùn)練專用的 OCR 模型
- 模板匹配:對于固定格式的驗證碼,使用模板匹配提高準(zhǔn)確率
- 多引擎融合:結(jié)合多個 OCR 引擎的結(jié)果提高準(zhǔn)確性
應(yīng)用場景
- 自動化測試:在自動化測試中識別驗證碼
- 數(shù)據(jù)采集:在合法的數(shù)據(jù)采集中處理驗證碼
- 腳本請求自動登錄:不采用人為干預(yù)進行自動識別登錄獲取token
測試結(jié)果

{
"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"
}
}
識別成功率
| 測試場景 | 成功率 | 平均響應(yīng)時間 |
|---|---|---|
| 清晰驗證碼 | 95%+ | < 2s |
| 模糊驗證碼 | 80%+ | < 3s |
| 復(fù)雜驗證碼 | 70%+ | < 4s |
示例識別結(jié)果
日志截圖
識別過程日志

總結(jié)
本項目實現(xiàn)了一個基于 Node.js 和 Tesseract.js 的驗證碼識別后端服務(wù),具有以下特點:
- 簡單易用:提供清晰的 RESTful API 接口
- 功能完整:支持從圖片識別到結(jié)果計算的完整流程
- 高度可定制:預(yù)留了圖片預(yù)處理等可擴展點
- 詳細信息:返回詳細的識別過程信息,便于調(diào)試
- 測試友好:包含完整的測試腳本
通過本項目,我們不僅實現(xiàn)了一個實用的驗證碼識別工具,也學(xué)習(xí)了如何使用 Tesseract.js 進行 OCR 識別,以及如何構(gòu)建一個完整的后端服務(wù)。
未來,我們可以通過添加更多的圖片預(yù)處理步驟、訓(xùn)練自定義模型等方式,進一步提高識別準(zhǔn)確率和性能,使其在更多場景下發(fā)揮作用。
代碼倉庫
https://github.com/JHJ1848/my-tools-common-captcha-reader.git

注意:本項目僅用于學(xué)習(xí)和合法用途,請勿用于任何惡意行為。使用驗證碼識別技術(shù)時,請遵守相關(guān)法律法規(guī)和網(wǎng)站的使用條款。
到此這篇關(guān)于基于Node.js和Tesseract.js實現(xiàn)驗證碼識別服務(wù)的文章就介紹到這了,更多相關(guān)Node.js和Tesseract.js驗證碼識別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Node.js使用MySQL出現(xiàn)connect ECONNREFUSED 127.0.0.1:3306的問題
這篇文章主要介紹了解決Node.js使用MySQL出現(xiàn)connect ECONNREFUSED 127.0.0.1:3306報錯的相關(guān)資料,文中將問題描述的很清楚,解決的方法也介紹的很完整,需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03
NodeJS學(xué)習(xí)筆記之Connect中間件模塊(一)
這是一個目錄概要,里面記錄著NodeJS的基礎(chǔ)知識部分,今天這篇文章以及后續(xù)的幾篇,將是一個進階系列,讓我們建立一個由淺入深的學(xué)習(xí)的過程,2015-01-01
Node.js中的HTTP?Server對象與GET、POST請求
這篇文章介紹了Node.js中的HTTP?Server對象與GET、POST請求,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07
nodejs使用socket5進行代理請求的實現(xiàn)
這篇文章主要介紹了nodejs使用socket5進行代理請求的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
Highcharts+NodeJS搭建數(shù)據(jù)可視化平臺示例
本篇文章主要介紹了Highcharts+NodeJS搭建數(shù)據(jù)可視化平臺,詳細的介紹了使用Highcharts框架的經(jīng)驗,有興趣的可以了解一下。2017-01-01
從零開始學(xué)習(xí)Node.js系列教程四:多頁面實現(xiàn)的數(shù)學(xué)運算示例
這篇文章主要介紹了Node.js多頁面實現(xiàn)的數(shù)學(xué)運算,涉及nodejs請求響應(yīng)、數(shù)值傳遞、運算等相關(guān)操作技巧,需要的朋友可以參考下2017-04-04
Node.js中Promise未處理的拒絕報錯的常見原因及解決方案
在Node.js應(yīng)用開發(fā)中,Promise未處理的拒絕(Unhandled Promise Rejection)是一個常見的錯誤,本文系統(tǒng)性總結(jié)Node.js中Promise未處理的拒絕報錯的常見原因及解決方案,并提供豐富的代碼和表格示例分析,需要的朋友可以參考下2025-06-06

