Jmeter驗(yàn)證碼識(shí)別插件實(shí)戰(zhàn)筆記

唉~衬吆,做個(gè)Web端的性能測(cè)試俱恶,第一步遇到的難題就是萬(wàn)惡的圖形驗(yàn)證碼,大家都知道驗(yàn)證碼的處理有以下幾點(diǎn):
1啥酱、找個(gè)善良樂(lè)于助人的開(kāi)發(fā)大大幫忙屏蔽一下驗(yàn)證碼
2、如果你和開(kāi)發(fā)大大關(guān)系夠鐵厨诸,開(kāi)個(gè)后門镶殷,整個(gè)萬(wàn)能驗(yàn)證碼
3、以上兩種都不可以的話微酬,掀桌(╯' - ')╯︵ ┻━┻走人~绘趋,

emmmm,開(kāi)玩笑的,趕緊快馬加鞭的gun回來(lái)颗管。以上兩種如果都不可以的話陷遮,咱們只能通過(guò)暴力手段,把開(kāi)發(fā)打殘了垦江。還是開(kāi)個(gè)玩笑了帽馋,畢竟是法制社會(huì)呢!言歸正傳比吭,以上兩種都不可以绽族,咱們只能寫(xiě)一個(gè)識(shí)別驗(yàn)證碼的插件了。
主要是參考大神的文章衩藤,我只是代碼的搬運(yùn)工https://blog.csdn.net/xreztento/article/details/48682923

一吧慢、準(zhǔn)備工具

1、Tesseract赏表,圖形圖像識(shí)別工具
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包導(dǎo)入到工程下

三坠韩、新建如下類

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+"http://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() {//設(shè)置顯示名稱
        // TODO Auto-generated method stub
        return "VcodeExtractor";
    }

    public void modifyTestElement(TestElement extractor) {
        // TODO Auto-generated method stub
        super.configureTestElement(extractor);

    }
}

以上前兩個(gè)類是圖像識(shí)別,后兩個(gè)是Jmeter的UI部分炼列。

四只搁、咱們可以寫(xiě)一個(gè)測(cè)試類,看一下執(zhí)行結(jié)果是否正確俭尖,測(cè)試類源碼如下

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);
         
     }

}

執(zhí)行測(cè)試類氢惋,結(jié)果如下圖


五、生成插件

生成插件稽犁,直接在項(xiàng)目右鍵-> export->Runnable jar file,生成.jar文件焰望。然后將生成的jar文件放在Jmeter的lib文件下的ext文件夾下。然后打開(kāi)Jmeter已亥,在后置處理器下會(huì)有驗(yàn)證碼識(shí)別的插件熊赖。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市虑椎,隨后出現(xiàn)的幾起案子震鹉,更是在濱河造成了極大的恐慌,老刑警劉巖捆姜,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件传趾,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡泥技,警方通過(guò)查閱死者的電腦和手機(jī)浆兰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)珊豹,“玉大人镊讼,你說(shuō)我怎么就攤上這事∑揭梗” “怎么了蝶棋?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)忽妒。 經(jīng)常有香客問(wèn)我玩裙,道長(zhǎng)兼贸,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任吃溅,我火速辦了婚禮溶诞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘决侈。我一直安慰自己螺垢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布赖歌。 她就那樣靜靜地躺著枉圃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪庐冯。 梳的紋絲不亂的頭發(fā)上孽亲,一...
    開(kāi)封第一講書(shū)人閱讀 52,785評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音展父,去河邊找鬼返劲。 笑死,一個(gè)胖子當(dāng)著我的面吹牛栖茉,可吹牛的內(nèi)容都是我干的篮绿。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼吕漂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼搔耕!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起痰娱,我...
    開(kāi)封第一講書(shū)人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤弃榨,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后梨睁,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體鲸睛,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年坡贺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了官辈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遍坟,死狀恐怖拳亿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愿伴,我是刑警寧澤肺魁,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站隔节,受9級(jí)特大地震影響鹅经,放射性物質(zhì)發(fā)生泄漏寂呛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一瘾晃、第九天 我趴在偏房一處隱蔽的房頂上張望贷痪。 院中可真熱鬧,春花似錦蹦误、人聲如沸劫拢。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)舱沧。三九已至,卻和暖如春哪廓,著一層夾襖步出監(jiān)牢的瞬間狗唉,已是汗流浹背初烘。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工涡真, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肾筐。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓哆料,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親吗铐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子东亦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容