jmeter对图片进行ocr识别

概述:多种方式实现对图片的ocr识别,识别可用于验证码,图片文字识别等

  1. 使用Tess4J识别验证码

    • 目前这个工具精度不是很高,但是他可以自己训练模型,提升精度,这里只记录使用方法,我试了两种不太复杂的,都识别错误,如果不是很简单的图,这个需要再训练或者找其他工具
    • 工具下载地址:https://sourceforge.net/projects/tess4j/

    (1)下载后进行解压,将Tess4J-3.4.8-src\Tess4J\lib和Tess4J-3.4.8-src\Tess4J\dist下的jar包都拷贝到apache-jmeter-5.5\lib路径下,然后重启jmeter
    (2)将图片或者验证码保存至本地
    (3)使用工具进行识别

    因为我的验证码接口返回的验证码是base加密后的字符串,所以在保存之前需要先解密,然后保存为图片

    image

    image

    使用的代码如下:

    import org.apache.commons.codec.binary.Base64;
    import java.io.*;
    import net.sourceforge.tess4j.*;
    
    Base64 base64=new Base64();
    byte[] data=base64.decode("${image}");
    
    String file_name = "D://code.png"; //代表存放文件的位置和文件名,路径和文件名需要自定义,路径需要提前创建
    File file = new File(file_name);
    FileOutputStream out = new FileOutputStream(file);
    out.write(data);
    out.close();
    
    vars.put("file_name",file_name);
    
    File imageFile1 = new File(file_name);//读取图片数字
    Tesseract instance = new Tesseract();  
    instance.setDatapath("D://Tools//ocr//Tess4J-3.4.8-src//Tess4J//tessdata"); //Tess4j 文件里的 tessdata 目录下
    instance.setLanguage("eng");//英文库识别数字比较准确
    content = instance.doOCR(imageFile1).replace("\n", "");
    vars.put("aaaaaa",content);
    
  2. 使用OcrServer进行识别

    (1)下载工具后,运行exe文件,会起一个本地127.0.0.1的http服务,端口为12349

    image
    (2) 如果你的验证码返回直接为图片base64加密后内容,那么直接把这个内容给ocr工具进行识别

    使用json提取出返回值中,图片base64的部分
    image
    然后添加一个HTTP请求
    image
    加一个察看结果树,运行,查看结果,识别验证码的请求和响应如下,已经报错,目前未解
    image
    image

    (3) 如果你的验证码返回直接是图片,那么需要对图片加密base64后,进行识别

    • 在获取验证码的请求后面,添加一个保存图片的监听器:保存响应到文件

      image

    • 然后在添加一个 取样器:JSR223 Sampler,对图片进行base64编码

      image

    使用的代码如下:

    SampleResult.setIgnore();
    
    import java.io.*;
    import org.apache.commons.codec.binary.Base64;
    
    String image=vars.get("png");
    log.info("开始打印:image");
    log.info(image);
    
    byte[] data = null;
    
    try {
    	InputStream in = new FileInputStream(image);
    	data = new byte[in.available()];
    	in.read(data);
    	in.close();
    
    } catch (IOException e) {
    	e.printStackTrace();
    }
    
    Base64 base64=new Base64();
    vars.put("base64",base64.encodeToString(data));
    
    • 最后添加一个HTTP请求,把加密好的数据发给ocr识别
      image
    • 添加一个察看结果树、调试取样器进行结果观察
      image
      image
  3. 使用ddddocr识别

    • 这是一个python的库,可以在jmeter中进行调用python脚本识别,然后输出给变量,在测试计划后续的请求中使用

    • 这个库精度还可以,识别的我验证码准确率挺高

    • 需要有python环境,然后安装ddddocr库
      (1)如果你的返回验证码直接是一个图片,那么需要先把图片保存在本地,保存方法看上面第二种方法,然后添加一个BeanShell 取样器,对保存好的图片进行识别

      image
      使用的代码如下:

      // 以cmd命令行方式调用py脚本,&&为多组命令连接符
      
      String cmd = "cmd /c cd D://git_code//xxxxxx//" + "&& python Identify_verification_code_for_jmeter.py  D://verification.jpg";   //cmd的参数 “/c” 表示当命令执行完成后关闭自身
      Runtime rt = Runtime.getRuntime();
      Process pr = rt.exec(cmd);
      
      pr.waitFor();
      
      BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
      String line = "";
      StringBuilder response = new StringBuilder();
      
      while((line = br.readLine()) != null) {
      	response.append(line);
      }
      
      br.close();
      
      String code = response.toString();
      
      //在日志终端打印一下
      log.info(code);
      
      // 设置成可在jmeter中使用的变量
      vars.put("code", response.toString());
      

      使用的python代码如下:

      import ddddocr
      import sys
      
      image = sys.argv[1]
      ocr = ddddocr.DdddOcr()
      with open(image, 'rb') as f:
      	img_bytes = f.read()
      res = ocr.classification(img_bytes)
      print(res)
      

      (2)如果你的返回是加密后的base64,那么不需要保存图片,直接把这个返回取出来给python脚本解码后识别即可
      在请求后加一个提取器,提出图片base64的部分,然后加一个BeanShell:
      image
      使用的代码如下:

      // 以cmd命令行方式调用py脚本,&&为多组命令连接符
       String cmd = "cmd /c cd D://git_code//xxxxxx//" + "&& python Identify_verification_code_for_jmeter.py" + " " + "${image}";   //cmd的参数 “/c” 表示当命令执行完成后关闭自身
       log.info(cmd);
       Runtime rt = Runtime.getRuntime();
       Process pr = rt.exec(cmd);
      
       pr.waitFor();
      
       BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
       String line = "";
       StringBuilder response = new StringBuilder();
      
       while((line = br.readLine()) != null) {
       	response.append(line);
       }
      
       br.close();
      
       String code = response.toString();
      
       //在日志终端打印一下
       log.info(code);
      
       // 设置成可在jmeter中使用的变量
       vars.put("code", response.toString());
      
      

      使用的python代码如下:

       import ddddocr
       import sys
       import base64
      
       image = sys.argv[1]
       ocr = ddddocr.DdddOcr()
      
       image_base64 = base64.b64decode(image)
       res = ocr.classification(bytes(image_base64))
       print(res)
      
posted @ 2023-03-29 17:34  wenwenliang  阅读(1319)  评论(0)    收藏  举报