🛠️ 项目日志:我用 Go 写了一个验证码识别器(OCR 实战)
验证码是个麻烦东西。在为公司做一个自动化测试系统的时候,前端登录页的验证码让我头疼了几天。为了解决这个问题,我用 Go 和 Tesseract 写了个小工具,能自动处理并识别验证码图片。本文是这次开发的完整记录,也许能帮到同样遇到验证码困扰的你。
🎯 问题背景
我们的系统在登录时必须输入验证码。自动化测试流程必须无人工干预,而验证码却让 CI/CD 卡了壳。
我考虑过几种方式:
后端绕过验证码:不行,验证码校验逻辑已经固化在服务端。
模拟输入:不现实,每次验证码都不一样。
OCR 自动识别:可行!但效果不能差。
我最终决定使用 Tesseract(开源 OCR 引擎)配合 Go 语言实现自动识别脚本。
🧱 技术方案拆解
核心目标:读取验证码图像,进行预处理,再使用 OCR 获取文字。
技术选型:
语言:Go(执行快,开发迅速)
OCR 引擎:Tesseract
图像预处理库:imaging + nfnt/resize
OCR 绑定:gosseract
⚙️ 环境搭建记录
安装 Tesseract:
macOS:
brew install tesseract
Linux (Ubuntu):
sudo apt install tesseract-ocr
Windows:去 GitHub 下载 .exe 安装。
安装 Go 包:
go get github.com/otiai10/gosseract/v2
go get github.com/disintegration/imaging
go get github.com/nfnt/resize
📸 图像预处理:关键步骤
验证码图像往往包含噪声、背景干扰,OCR 直接识别很容易出错。所以我加了一些预处理步骤:
更多内容访问ttocr.com或联系1436423940
灰度处理:去除颜色干扰
二值化:将图像转成黑白,强化文字与背景的对比
缩放图像:提高分辨率,OCR 识别更清晰
🔍 实现代码
main.go
package main
import (
"fmt"
"image"
"image/color"
"log"
"os"
"github.com/disintegration/imaging"
"github.com/nfnt/resize"
"github.com/otiai10/gosseract/v2"
)
func preprocess(srcPath, dstPath string) error {
f, err := os.Open(srcPath)
if err != nil {
return err
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
return err
}
gray := imaging.Grayscale(img)
processed := image.NewRGBA(gray.Bounds())
for y := 0; y < gray.Bounds().Dy(); y++ {
for x := 0; x < gray.Bounds().Dx(); x++ {
p := color.GrayModel.Convert(gray.At(x, y)).(color.Gray)
if p.Y > 120 {
processed.Set(x, y, color.White)
} else {
processed.Set(x, y, color.Black)
}
}
}
scaled := resize.Resize(300, 0, processed, resize.Lanczos3)
return imaging.Save(scaled, dstPath)
}
func main() {
err := preprocess("captcha.png", "clean.png")
if err != nil {
log.Fatalf("图像预处理失败: %v", err)
}
client := gosseract.NewClient()
defer client.Close()
client.SetImage("clean.png")
client.SetPageSegMode(gosseract.PSM_SINGLE_LINE)
client.SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
text, err := client.Text()
if err != nil {
log.Fatalf("OCR 识别失败: %v", err)
}
fmt.Println("验证码内容:", text)
}
✅ 实际效果
我测试了几十张验证码图片,识别成功率在 80%-90% 之间。如果遇到背景特别复杂、字符粘连的图像,准确率会有所下降。
不过对于我们系统里的验证码(白底黑字 + 固定长度 + 无扭曲),识别表现非常稳定。
🧠 一些技巧总结
字符集限制:Tesseract 默认会尝试识别各种字符,可以通过 SetVariable("tessedit_char_whitelist", "...") 让它只识别数字或大写字母。
PSM 设置:SetPageSegMode(6) 表示“假设是单一文本行”,比默认效果更好。
图像分辨率重要:低分辨率 OCR 表现差,适当放大图像可显著提升识别率。
📦 项目结构建议
captcha-decoder/
├── main.go
├── captcha.png
├── clean.png
├── go.mod验证码是个麻烦东西。在为公司做一个自动化测试系统的时候,前端登录页的验证码让我头疼了几天。为了解决这个问题,我用 Go 和 Tesseract 写了个小工具,能自动处理并识别验证码图片。本文是这次开发的完整记录,也许能帮到同样遇到验证码困扰的你。
🎯 问题背景
我们的系统在登录时必须输入验证码。自动化测试流程必须无人工干预,而验证码却让 CI/CD 卡了壳。
我考虑过几种方式:
后端绕过验证码:不行,验证码校验逻辑已经固化在服务端。
模拟输入:不现实,每次验证码都不一样。
OCR 自动识别:可行!但效果不能差。
我最终决定使用 Tesseract(开源 OCR 引擎)配合 Go 语言实现自动识别脚本。
🧱 技术方案拆解
核心目标:读取验证码图像,进行预处理,再使用 OCR 获取文字。
技术选型:
语言:Go(执行快,开发迅速)
OCR 引擎:Tesseract
图像预处理库:imaging + nfnt/resize
OCR 绑定:gosseract
⚙️ 环境搭建记录
安装 Tesseract:
macOS:
brew install tesseract
Linux (Ubuntu):
sudo apt install tesseract-ocr
Windows:去 GitHub 下载 .exe 安装。
安装 Go 包:
go get github.com/otiai10/gosseract/v2
go get github.com/disintegration/imaging
go get github.com/nfnt/resize
📸 图像预处理:关键步骤
验证码图像往往包含噪声、背景干扰,OCR 直接识别很容易出错。所以我加了一些预处理步骤:
灰度处理:去除颜色干扰
二值化:将图像转成黑白,强化文字与背景的对比
缩放图像:提高分辨率,OCR 识别更清晰
🔍 实现代码
main.go
package main
import (
"fmt"
"image"
"image/color"
"log"
"os"
"github.com/disintegration/imaging"
"github.com/nfnt/resize"
"github.com/otiai10/gosseract/v2"
)
func preprocess(srcPath, dstPath string) error {
f, err := os.Open(srcPath)
if err != nil {
return err
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
return err
}
gray := imaging.Grayscale(img)
processed := image.NewRGBA(gray.Bounds())
for y := 0; y < gray.Bounds().Dy(); y++ {
for x := 0; x < gray.Bounds().Dx(); x++ {
p := color.GrayModel.Convert(gray.At(x, y)).(color.Gray)
if p.Y > 120 {
processed.Set(x, y, color.White)
} else {
processed.Set(x, y, color.Black)
}
}
}
scaled := resize.Resize(300, 0, processed, resize.Lanczos3)
return imaging.Save(scaled, dstPath)
}
func main() {
err := preprocess("captcha.png", "clean.png")
if err != nil {
log.Fatalf("图像预处理失败: %v", err)
}
client := gosseract.NewClient()
defer client.Close()
client.SetImage("clean.png")
client.SetPageSegMode(gosseract.PSM_SINGLE_LINE)
client.SetVariable("tessedit_char_whitelist", "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
text, err := client.Text()
if err != nil {
log.Fatalf("OCR 识别失败: %v", err)
}
fmt.Println("验证码内容:", text)
}
✅ 实际效果
我测试了几十张验证码图片,识别成功率在 80%-90% 之间。如果遇到背景特别复杂、字符粘连的图像,准确率会有所下降。
不过对于我们系统里的验证码(白底黑字 + 固定长度 + 无扭曲),识别表现非常稳定。
🧠 一些技巧总结
字符集限制:Tesseract 默认会尝试识别各种字符,可以通过 SetVariable("tessedit_char_whitelist", "...") 让它只识别数字或大写字母。
PSM 设置:SetPageSegMode(6) 表示“假设是单一文本行”,比默认效果更好。
图像分辨率重要:低分辨率 OCR 表现差,适当放大图像可显著提升识别率。
📦 项目结构建议
captcha-decoder/
├── main.go
├── captcha.png
├── clean.png
├── go.mod
浙公网安备 33010602011771号