使用tess4j识别图片验证码
1.下载tess4j,下载地址https://sourceforge.net/projects/tess4j/
2.编写ocr识别类OCRUtil
参考代码:
package com.gzy.OCR;
import java.io.File;
import org.testng.annotations.Test;
import net.sourceforge.tess4j.ITesseract;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
/**
* OCR识别工具类,调用tess4j实现OCR识别
* 注意:
* 1.tess4j核心包和lib下所有jar包均需要引入
* 2.拷贝tessdata文件夹于当前用户目录
*/
public class OCRUtil {
public OCRUtil() {
}
@Test
public void test() {
File imageFile = new File("C:/Users/gzy/Desktop/tess4j/image.jpeg");
System.out.println(getOCRResult(imageFile));
}
public static String getOCRResult(File file) {
ITesseract instance = new Tesseract();
String result = null;
try {
result = instance.doOCR(file);
} catch (TesseractException e) {
System.out.println(e.getMessage());
} finally {
file.delete();
}
return result;
}
}
3.编写验证码准确性校验类VcodeUtils
VcodeUtils参考代码
package com.gzy.OCR;
import org.testng.annotations.Test;
/**
* 验证码正确性校验,分别校验纯数字、纯字母、以及数字+字母的准确性
*/
public class VcodeUtils {
private final static String PATTERNINT = "0123456789";
private final static String PATTERNAbc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
private final static String PATTERNAbcAndINT = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
public VcodeUtils() {
}
@Test
public void test() {
String str = vcode(" 1 a 3V ", 3, 4);
System.out.println("--->>" + str + "<<---");
}
public static String vcode(String vcode, int type, int len) {
vcode = vcode.trim();
vcode = vcode.replace(" ", "");
char[] vcodeChar = vcode.toCharArray();
if (vcodeChar.length != len) {
vcode = "error";
return vcode;
}
if (type == 1) {
// 纯数字
for (int i = 0; i < len; i++) {
if (PATTERNINT.indexOf(vcode.toCharArray()[i]) < 0) {
vcode = "error";
return vcode;
}
}
} else if (type == 2) {
// 纯字母
for (int i = 0; i < len; i++) {
if (PATTERNAbc.indexOf(vcode.toCharArray()[i]) < 0) {
vcode = "error";
return vcode;
}
}
} else {
// 数字字母混合
for (int i = 0; i < len; i++) {
if (PATTERNAbcAndINT.indexOf(vcode.toCharArray()[i]) < 0) {
vcode = "error";
return vcode;
}
}
}
return vcode;
}
}
4.通过TestBean框架创建VcodeExtractor组件
编写VcodeExtractor类,实现验证码识别逻辑
package com.gzy.OCR;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.jmeter.processor.PostProcessor;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.testelement.AbstractScopedTestElement;
import org.apache.jmeter.threads.JMeterContext;
import org.apache.jmeter.threads.JMeterVariables;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;
/**
* 1.VcodeExtractor实现逻辑,继承AbstractScopedTestElement类,实现PostProcessor, TestBean
* 2.AbstractScopedTestElement类是AbstractTestElement子类
* 3.定义属性myFile,vcodeLen,vcodeType,imageType,所有属性都必须有共有的get、set方法
* myFile:对应界面上选择文件操作
* vcodeLen:验证码长度
* vcodeType:验证码类型
* imageType:验证码图片类型
*/
public class VcodeExtractor extends AbstractScopedTestElement implements PostProcessor, TestBean {
private File myFile;
private int vcodeLen;
private String vcodeType;
private String imageType;
private int Type = 0;
//定义 UID
private static final long serialVersionUID = 241L;
//获取日志类
private static final Logger log = LoggingManager.getLoggerForClass();
//定义属性vcode默认值
private String vcode = "error";
public File getMyFile() {
return myFile;
}
public void setMyFile(File myFile) {
this.myFile = myFile;
}
public int getVcodeLen() {
return vcodeLen;
}
public void setVcodeLen(int vcodeLen) {
this.vcodeLen = vcodeLen;
}
public String getVcodeType() {
return vcodeType;
}
public void setVcodeType(String vcodeType) {
this.vcodeType = vcodeType;
}
public String getImageType() {
return imageType;
}
public void setImageType(String imageType) {
this.imageType = imageType;
}
@SuppressWarnings("finally")
@Override
public void process() {
// 重写process方法,实现操作逻辑
JMeterContext context = getThreadContext();
SampleResult previousResult = context.getPreviousResult();
if (previousResult == null) {
return;
}
switch (vcodeType) {
case "纯数字":
Type = 1;
break;
case "纯字母":
Type = 2;
break;
default:
Type = 0;
break;
}
String status = previousResult.getResponseCode();
int id = context.getThreadNum();
String imageName = id + "." + imageType;
if (status.equals("200")) {
// 如果响应码未200,则读取响应流生成对应验证码图片
byte[] buffer = previousResult.getResponseData();
FileOutputStream out = null;
File file = null;
try {
file = new File(imageName);
out = new FileOutputStream(file);
out.write(buffer);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
log.info("打印用户路径--->>开始");
log.info(System.getProperty("user.dir"));
log.info("打印用户路径--->>结束");
log.info("识别验证码--->>开始");
//调用OCRUtil.getOCRResult()识别图片验证码
vcode = OCRUtil.getOCRResult(file);
log.info("原始验证码--->>开始");
log.info(vcode);
log.info("原始验证码--->>结束");
//调用VcodeUtils.vcode()对识别出来的验证码做正确性校验和处理
vcode = VcodeUtils.vcode(vcode, Type, vcodeLen);
log.info("最终验证码--->>开始");
log.info(vcode);
log.info("最终验证码--->>结束");
//将获取的验证码存入vcode属性供?Jmeter调用者使用,如果识别不成功,保存的值为error
JMeterVariables var = context.getVariables();
var.put("vcode", vcode);
var.put("vuser", String.valueOf(id));
log.info("识别验证码--->>结束");
return;
}
}
}
} else {
//提供直接测试方法,选取本地图片查看识别结果是否准确
if (myFile != null && myFile.exists() && myFile.canRead()) {
log.info("打印用户路径--->>开始");
log.info(System.getProperty("user.dir"));
log.info("打印用户路径--->>结束");
log.info("识别验证码--->>开始");
vcode = OCRUtil.getOCRResult(myFile);
log.info("原始验证码--->>开始");
log.info(vcode);
log.info("原始验证码--->>结束");
vcode = VcodeUtils.vcode(vcode, Type, vcodeLen);
log.info("最终验证码--->>开始");
log.info(vcode);
log.info("最终验证码--->>结束");
JMeterVariables var = context.getVariables();
var.put("vcode", vcode);
var.put("vuser", String.valueOf(id));
log.info("识别验证码--->>结束");
return;
}
JMeterVariables var = context.getVariables();
var.put("vcode", vcode);
var.put("vuser", String.valueOf(id));
log.error("图片不存在或者获取图片响应流失败!");
}
}
}
编写VcodeExtractorBeanInfo类,定义UI属性
package com.gzy.OCR;
import java.beans.PropertyDescriptor;
import org.apache.jmeter.testbeans.BeanInfoSupport;
import org.apache.jmeter.testbeans.TestBean;
import org.apache.jmeter.testbeans.gui.TableEditor;
/**
* 1.继承BeanInfoSupport类
* 2.通过getprop()方法设置各属性默认值
*/
public class VcodeExtractorBeanInfo extends BeanInfoSupport {
private PropertyDescriptor getprop(String name) {
final PropertyDescriptor property = property(name);
property.setValue(NOT_UNDEFINED, Boolean.FALSE);
return property;
}
private PropertyDescriptor getprop(String name, Object deflt) {
PropertyDescriptor p = property(name);
p.setValue(DEFAULT, deflt);
p.setValue(NOT_UNDEFINED, Boolean.TRUE);
return p;
}
public VcodeExtractorBeanInfo() {
//无参构造函数关联VcodeExtractor
super(VcodeExtractor.class);
getprop("myFile");
// 设置验证码长度默认为4位
getprop("vcodeLen", Integer.valueOf(4));
PropertyDescriptor p = property("vcodeLen");
p.setShortDescription("输入验证码长度,可輸入項: 任意正整数");
// 设置验证码类型默认为数字+字母
getprop("vcodeType", "数字+字母");
p = property("vcodeType");
p.setShortDescription("输入验证码格式,可输入项:纯数字、纯字母、数字+字母");
// 设置验证码图片类型默认为jpg
getprop("imageType", "jpg");
p = property("imageType");
p.setShortDescription("输入验证码图片类型,可输入项:jpg、jpeg、png");
}
}
编写VcodeExtractorResources.properties定义各默认属性展示名称
displayName=gzy@VcodeExtractor
myFile.displayName=选择图片路径
vcodeLen.displayName=验证码长度
vcodeType.displayName=验证码类型
imageType.displayName=图片类型
注意:
1.使用tess4j除了需要引入tess4j-3.3.1.jar包外还需要引入其源码lib目录下的所有文件
2.需将该插件所依赖的所有jar包放入Jmeter下lib目录(或者全部存入统一文件夹,然后在jmeter.properties文件下修改user.classpath属性,如user.classpath=../classes;../lib;../lib/Tess4J/lib)
3.需要将tess4j的tessdata文件夹拷贝至Jmeter运行时用户目录,即bin目录
---------------------
作者:天天爱代码
来源:CSDN
原文:https://blog.csdn.net/u012421039/article/details/68944428
版权声明:本文为博主原创文章,转载请附上博文链接!