美文网首页
Jmeter验证码识别插件实战笔记

Jmeter验证码识别插件实战笔记

作者: 我吃小虾米 | 来源:发表于2018-06-03 16:16 被阅读0次

    唉~,做个Web端的性能测试,第一步遇到的难题就是万恶的图形验证码,大家都知道验证码的处理有以下几点:
    1、找个善良乐于助人的开发大大帮忙屏蔽一下验证码
    2、如果你和开发大大关系够铁,开个后门,整个万能验证码
    3、以上两种都不可以的话,掀桌(╯' - ')╯︵ ┻━┻走人~,

    emmmm,开玩笑的,赶紧快马加鞭的gun回来。以上两种如果都不可以的话,咱们只能通过暴力手段,把开发打残了。还是开个玩笑了,毕竟是法制社会呢!言归正传,以上两种都不可以,咱们只能写一个识别验证码的插件了。
    主要是参考大神的文章,我只是代码的搬运工https://blog.csdn.net/xreztento/article/details/48682923

    一、准备工具

    1、Tesseract,图形图像识别工具
    2、ApacheJmeter_core.jar,
    3、 jorphon.jar
    4、logkit-2.0.jar
    5、jai-imageio-1.1.jar
    6、 swingx-1.6.1.jar
    7、eclipse

    二、安装Tesseract,将需要用的jar包导入到工程下

    三、新建如下类

    ImageIOHelper.java

    import java.awt.Color;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import java.util.Iterator;
    import java.util.Locale;
    
    import javax.imageio.IIOImage;
    import javax.imageio.ImageIO;
    import javax.imageio.ImageReader;
    import javax.imageio.ImageWriteParam;
    import javax.imageio.ImageWriter;
    import javax.imageio.metadata.IIOMetadata;
    import javax.imageio.stream.ImageInputStream;
    import javax.imageio.stream.ImageOutputStream;
    
    import com.sun.media.imageio.plugins.tiff.TIFFImageWriteParam;
    
    
    public class ImageIOHelper{
    public static File createImage(File imageFile, String imageFormat) {
    
        File tempFile = null;
        ImageInputStream iis = null;
        ImageOutputStream ios = null;
        ImageReader reader = null;
        ImageWriter writer = null;
    
        try {
            Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName(imageFormat);
            reader = readers.next();
    
            iis = ImageIO.createImageInputStream(imageFile);
            reader.setInput(iis);
    
            IIOMetadata streamMetadata = reader.getStreamMetadata();
                        TIFFImageWriteParam tiffWriteParam = new TIFFImageWriteParam(Locale.CHINESE);
            tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
            Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("tiff");
            writer = writers.next();
    
            BufferedImage bi = removeBackgroud(reader.read(0));
            IIOImage image = new IIOImage(bi,null,reader.getImageMetadata(0));
            tempFile = tempImageFile(imageFile);
    
            ios = ImageIO.createImageOutputStream(tempFile);
            writer.setOutput(ios);
            writer.write(streamMetadata, image, tiffWriteParam);
    
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if(iis != null){
                try {
                    iis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(ios != null){
                try {
                    ios.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(writer != null){
                writer.dispose();
            }
            if(reader != null){
                reader.dispose();
            }
    
        }
    
        return tempFile;
    }
    
    private static File tempImageFile(File imageFile) {
        String path = imageFile.getPath();
        StringBuffer strB = new StringBuffer(path);
        return new File(strB.toString().replaceFirst("jpg", "tif"));
     
    }
    public static int isFilter(int colorInt) {  
        Color color = new Color(colorInt);
        if ((color.getRed() > 85 && color.getRed() < 255) 
                && (color.getGreen() > 85 && color.getGreen() < 255) 
                && (color.getBlue() > 85 && color.getBlue() < 255)) {  
            return 1;  
        }  
        return 0;
    }  
    
    public static BufferedImage removeBackgroud(BufferedImage img)  
            throws Exception {  
        int width = img.getWidth();  
        int height = img.getHeight();  
        for (int x = 0; x < width; ++x) {  
            for (int y = 0; y < height; ++y) {  
                if (isFilter(img.getRGB(x, y)) == 1) {  
                    img.setRGB(x, y, Color.WHITE.getRGB());  
                }
            }  
        }  
        return img;
    }
    }
    

    OCR.java

    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.List;
    
    
    public class OCR {
        private final String LANG_OPTION = "-l";
        private final String EOL = System.getProperty("line.separator");
        private String tessPath = "D://Tesseract-OCR";
    
        public String recognizeText(File imageFile,String imageFormat) {
            
            File tempImage = ImageIOHelper.createImage(imageFile,imageFormat);
            File outputFile = new File(imageFile.getParentFile(),"output" + imageFile.getName());
            StringBuffer sb = new StringBuffer();
            List<String> cmd = new ArrayList<String>();
    
            cmd.add(tessPath+"//tesseract");
            cmd.add("");
            cmd.add(outputFile.getName());
            cmd.add(LANG_OPTION);
            cmd.add("eng");     
            ProcessBuilder pb = new ProcessBuilder();
            pb.directory(imageFile.getParentFile());
    
            cmd.set(1, tempImage.getName());
            pb.command(cmd);
            pb.redirectErrorStream(true);
    
            Process process = null;
            BufferedReader in = null;
            int wait;
            try {
                process = pb.start();
                //tesseract.exe xxx.tif 1 -l eng
                wait = process.waitFor();
                if(wait == 0){
                    in = new BufferedReader(new InputStreamReader(new FileInputStream(outputFile.getAbsolutePath()+".txt"),"UTF-8"));
                    String str;
                    while((str = in.readLine())!=null){
                        sb.append(str).append(EOL);
                    }
                    in.close();
    
                }else{
    
                    tempImage.delete();
                }
                new File(outputFile.getAbsolutePath()+".txt").delete();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if(in != null){
                    try {
                        in.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    
            tempImage.delete();
            return sb.toString();
        }
    }
    

    VcodeExtractor.java

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.Serializable;
    
    import org.apache.jmeter.processor.PostProcessor;
    import org.apache.jmeter.samplers.SampleResult;
    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;
    
    public class VcodeExtractor extends AbstractScopedTestElement implements PostProcessor, Serializable{
        private static final Logger log = LoggingManager.getLoggerForClass();
        public void process() {
            // TODO Auto-generated method stub
            JMeterContext context = getThreadContext();
            SampleResult previousResult = context.getPreviousResult();
            if (previousResult == null) {
                return;
            }
            log.debug("VcodeExtractor processing result");
    
            String status = previousResult.getResponseCode();
            int id = context.getThreadNum();
            String imageName = id + ".jpg";
    
            if(status.equals("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) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    if(out != null){
                        try {
                            out.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
    
                  try {   
                    String vcode = new OCR().recognizeText(file, "jpg"); 
                    vcode = vcode.replace(" ", "").trim();
    
                    JMeterVariables var = context.getVariables();
                    var.put("vcode", vcode);
                    var.put("vuser", String.valueOf(id));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }    
            }
    
        }
    
    }
    

    VcodeExtractorGUI.java

    import org.apache.jmeter.processor.gui.AbstractPostProcessorGui;
    import org.apache.jmeter.testelement.TestElement;
    
    public class VcodeExtractorGUI extends AbstractPostProcessorGui{
    
        public TestElement createTestElement() {
            // TODO Auto-generated method stub
            VcodeExtractor extractor = new VcodeExtractor();
            modifyTestElement(extractor);
            return extractor;
        }
    
        public String getLabelResource() {
            // TODO Auto-generated method stub
            return this.getClass().getName();
        }
    
        @Override
        public String getStaticLabel() {//设置显示名称
            // TODO Auto-generated method stub
            return "VcodeExtractor";
        }
    
        public void modifyTestElement(TestElement extractor) {
            // TODO Auto-generated method stub
            super.configureTestElement(extractor);
    
        }
    }
    

    以上前两个类是图像识别,后两个是Jmeter的UI部分。

    四、咱们可以写一个测试类,看一下执行结果是否正确,测试类源码如下

    ReadPicture.java

    import java.io.File;
    import java.io.IOException;
    
    public abstract class ReadPicture {
    
         public static void main(String[] args) throws IOException {  
             File imageFile = new File("D://123.png");
             System.out.println(imageFile.getAbsolutePath());
             OCR ocr = new OCR();
             String recognizeText = ocr.recognizeText(imageFile, "png");
             System.out.println(recognizeText);
             
         }
    
    }
    

    执行测试类,结果如下图


    五、生成插件

    生成插件,直接在项目右键-> export->Runnable jar file,生成.jar文件。然后将生成的jar文件放在Jmeter的lib文件下的ext文件夹下。然后打开Jmeter,在后置处理器下会有验证码识别的插件。

    相关文章

      网友评论

          本文标题:Jmeter验证码识别插件实战笔记

          本文链接:https://www.haomeiwen.com/subject/armjsftx.html