在Mac上使用JMeter实现图片验证码识别的完整方案
详细包括下载软件等步骤
一、接口现状
接口1:获取图片验证码
接口2:发送短信
接口3:短信验证码登录
二、步骤简介
- 把接口返回值转换成图片保存在本地
- 利用JSR223 后置处理程序、OCR工具识别图片上的数字
- 引用识别到的图片验证码
- 发送短信验证码
- 利用调试取样器、JSR223 后置处理程序实现收到验证码,先输入,再运行注册接口
三、环境准备与软件安装
1.安装Tesseract OCR(核心识别引擎)
# 使用Homebrew安装Tesseract
brew install tesseract
# 安装中文语言包(如需识别中文验证码)
brew install tesseract-lang
- 安装图像处理工具(提高识别率)
# 安装ImageMagick用于图像预处理
brew install imagemagick
# 安装Ghostscript(依赖项)
brew install ghostscript
- 验证安装结果
# 检查Tesseract安装
tesseract --version
tesseract --list-langs # 应能看到eng/chr_sim等语言包
# 检查ImageMagick安装
convert --version
4.权限配置
# 检查临时目录权限
ls -ld /tmp
# 确保JMeter有权限访问临时目录
sudo chmod -R 777 /tmp
5.环境变量配置
# 编辑~/.zshrc文件
nano ~/.zshrc
# 添加以下内容
export TESSDATA_PREFIX=/usr/local/share/tessdata
export PATH="/usr/local/bin:$PATH"
# 使配置生效
source ~/.zshrc
# 强制刷新环境变量
exec $SHELL
6.验证语言包路径
# 查看语言包实际存放位置
ls /usr/local/share/tessdata/
ls /usr/share/tesseract-ocr/tessdata/
7.检查ImageMagick环境变量
# 检查convert命令路径
which convert
(预期结果:/usr/local/bin/convert)
# 检查ImageMagick版本
convert --version
(应显示版本信息(如7.0.11))
# 检查支持的图片格式(可选)
convert -list format
四、jmeter结构配置
1、整体结构
2、json提取器
imgBase64
$.data.base64
imgKey
$.data.imgKey
3、JSR223 后置处理程序
import org.apache.commons.codec.binary.Base64
import java.nio.file.*
def captchaFile = null
def processedFile = null
def savePath = "/Users/测试地址/Downloads/code.jpg" // 指定保存路径
try {
// 1. 获取并验证输入数据
def base64Data = vars.get("imgBase64")
def imgKey = vars.get("imgKey")
log.info("开始处理验证码,imgKey: ${imgKey}")
// 2. 检查关键数据是否存在
if (imgKey == null || imgKey == "NOT_FOUND" || imgKey == "0") {
def response = prev.getResponseDataAsString()
def json = new groovy.json.JsonSlurper().parseText(response)
base64Data = json.data?.base64
imgKey = json.data?.imgKey
if (!imgKey) {
throw new Exception("无法从响应中提取imgKey")
}
}
// 3. 检查Base64数据
if (!base64Data?.contains(",")) {
base64Data = "data:image/png;base64," + base64Data
}
// 4. 解码并保存图片
def imageBytes = Base64.decodeBase64(base64Data.split(",")[1])
def tempDir = System.getProperty("java.io.tmpdir")
captchaFile = new File(tempDir, "jmeter_captcha_${System.currentTimeMillis()}.png")
Files.write(captchaFile.toPath(), imageBytes)
// 5. 将图片保存到指定路径(新增代码)
def saveFile = new File(savePath)
if (!saveFile.parentFile.exists()) {
saveFile.parentFile.mkdirs()
}
Files.copy(captchaFile.toPath(), saveFile.toPath(), StandardCopyOption.REPLACE_EXISTING)
log.info("验证码图片已保存到: ${savePath}")
// 6. 图像预处理
processedFile = new File(tempDir, "processed_${captchaFile.name}")
def cmd = ["convert", captchaFile.path, "-threshold", "50%", processedFile.path]
new ProcessBuilder(cmd).start().waitFor()
// 7. OCR识别
def tesseractCmd = ["tesseract", processedFile.path, "stdout", "--psm", "7"]
def process = new ProcessBuilder(tesseractCmd).start()
def verificationCode = process.inputStream.text.trim()
verificationCode = verificationCode.replaceAll("[^0-9]", "")
// 8. 验证结果
if (verificationCode.matches("\\\\d{4}")) {
vars.put("captchaCode", verificationCode)
log.info("验证码识别成功: ${verificationCode}")
} else {
throw new Exception("识别结果不符合4位数字格式: ${verificationCode}")
}
} catch (Exception e) {
log.error("验证码处理失败: " + e.getMessage())
throw e
} finally {
// 清理临时文件(保留下载目录的文件)
captchaFile?.delete()
processedFile?.delete()
}
4、调试取样器
下面的JSR223 后置处理程序
// 在Debug Sampler后添加JSR223 PostProcessor
def userInput = javax.swing.JOptionPane.showInputDialog("请输入手机收到的4位验证码:")
vars.put("smsCode", userInput)
5、引用
(1)发送短信验证码
//接口本身
https://域名/api/mis-engine-eco-farm/sms/register?phone=19212345678&imgKey=71777123d42149548700378361a449e4&imgCode=4189
//引用
https://域名/api/mis-engine-eco-farm/sms/register?phone=19212345678&imgKey=${imgKey}&imgCode=${captchaCode}
(2)短信验证码注册用户