java實現自動識別驗證碼並自動填寫提交(調用百度通用文字識別OCR接口+大圖找小圖之圖像識別算法+模擬鼠標鍵盤動作)

一、使用的技術:

1.調用百度AI通用文字識別OCR接口

2.圖像識別算法

二、實現方案與步驟:

1.得到驗證碼的圖片的座標:先將驗證碼截圖,然後再對整個電腦屏幕截圖,通過大圖找小圖的方法,計算出小圖在大圖中的座標,從而得到驗證碼的座標。

2.通過驗證碼的座標實現每次截驗證碼的圖片的精準座標,每次通過該座標來截圖,調用文字識別接口,實現驗證碼的識別,識別之後,複製到剪貼板。

3.截驗證碼提交表單的小圖,再截整個電腦屏幕,通過大圖找小圖的方法,計算出小圖在大圖中的圖標,從而得到提交框的座標。

4.通過java模擬鼠標動作移動到驗證碼提交框的座標上再模擬點擊鼠標,鼠標的光標在提交框裏,讓提交框是輸入狀態,再通過模擬鍵盤動作Ctrl+v,把剛纔複製到剪貼板的驗證碼粘貼到提交框。

5.截驗證碼提交按鈕的小圖,再截整個電腦屏幕,通過大圖找小圖的方法,計算出小圖在大圖中的圖標,從而得到提交按鈕的座標。

6.通過java模擬鼠標動作移動到驗證碼提交按鈕的座標上再模擬點擊鼠標。

以上就是java實現自動識別驗證碼並自動填寫提交的完整方案。

三、具體實現:

1.如何調用百度AI通用文字識別接口?

(1)在瀏覽器輸入網址http://ai.baidu.com/或者百度搜索‘百度AI’點擊官網那個。點擊主頁的產品服務,看到通用文字識別,選擇技術文檔,下載Java SDK,解壓後得到4個jar包。或者直接從我雲盤下:百度網盤 提取碼:p8sc
把解壓後的文件複製粘貼到eclipse的項目的文件夾裏。
我項目名字是Test1。在這裏插入圖片描述

(2)刷新項目,選中剛纔複製過來的文件夾,右鍵單擊add build path,或者右鍵項目Build Path -> Add JARs選擇那4個jar包,確定。

(3)使用百度ai圖片文字識別的接口前還需要 API Key和clientSecret ,得申請一個。首先進入控制檯:(前提是已有百度賬號:如百度雲盤、貼吧等等)
在這裏插入圖片描述
選擇:產品服務–>人工智能–>文字識別
在這裏插入圖片描述
點擊:創建應用
在這裏插入圖片描述
創建好了就會如下圖所示,AppId、API Key、Secret Key都是有值的。到時候在代碼裏把這些值填進去就好。

在這裏插入圖片描述

2.代碼實現:

(1)如何調用這個接口呢?

在我們的項目Test1文件夾裏新建java類文件,話不多說,直接上代碼:

1.先給一下maven 依賴三個:
在這裏插入圖片描述
2.引用的庫:
在這裏插入圖片描述
3.AuthService.java

package test1;

import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;


public class AuthService {

    /**
     * 獲取權限token
     * @return 返回示例:
     * {
     * "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567",
     * "expires_in": 2592000
     * }
     */
    public static String getAuth() {
        // 官網獲取的 API Key 更新爲你註冊的
        String clientId = "這裏填你申請到的API Key";
        // 官網獲取的 Secret Key 更新爲你註冊的
        String clientSecret = "這裏填你申請到的Secret Key";
        return getAuth(clientId, clientSecret);
    }

    /**
     * 獲取API訪問token
     * 該token有一定的有效期,需要自行管理,當失效時需重新獲取.
     * @param ak - 百度雲官網獲取的 API Key
     * @param sk - 百度雲官網獲取的 Securet Key
     * @return assess_token 示例:
     * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567"
     */
    private static String getAuth(String ak, String sk) {
        // 獲取token地址
        String authHost = "https://aip.baidubce.com/oauth/2.0/token?";
        String getAccessTokenUrl = authHost
                // 1. grant_type爲固定參數
                + "grant_type=client_credentials"
                // 2. 官網獲取的 API Key
                + "&client_id=" + ak
                // 3. 官網獲取的 Secret Key
                + "&client_secret=" + sk;
        try {
            URL realUrl = new URL(getAccessTokenUrl);
            // 打開和URL之間的連接
            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();
            connection.setRequestMethod("GET");
            connection.connect();
            // 獲取所有響應頭字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍歷所有的響應頭字段
            for (String key : map.keySet()) {
              //  System.out.println(key + "--->" + map.get(key));
            }
            // 定義 BufferedReader輸入流來讀取URL的響應
            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            StringBuilder result = new StringBuilder();
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            /**
             * 返回結果示例
             */
          // System.out.println("result:" + result);
            JSONObject jsonObject = new JSONObject(result.toString());
            return jsonObject.getString("access_token");
        } catch (Exception e) {
           //System.out.printf("獲取token失敗!");
            e.printStackTrace(System.err);
        }
        return null;
    }

   public void main(String[] args) {
        getAuth();
    }
}

4.BaseImg64.java

package test1;

import sun.misc.BASE64Encoder;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * 圖片轉化base64後再UrlEncode結果
 */
@SuppressWarnings("restriction")
public class BaseImg64 {
    /**
     * 將一張本地圖片轉化成Base64字符串
     * @param imgPath 本地圖片地址
     * @return 圖片轉化base64後再UrlEncode結果
     */
	public static String getImageStrFromPath(String imgPath) { 
		InputStream in; 
		byte[] data = null; 
		// 讀取圖片字節數組 
		try { 
			in = new FileInputStream(imgPath); 
			data = new byte[in.available()];
			in.read(data); in.close(); 
		} catch (IOException e) {
			e.printStackTrace(); } 
		// 對字節數組Base64編碼
		BASE64Encoder encoder = new BASE64Encoder();
		// 返回Base64編碼過再URLEncode的字節數組字符串
		
		try {
			return URLEncoder.encode(encoder.encode(data),"UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
   }
}

  1. EasySpecProvider.java
package test1;

import org.apache.http.cookie.CookieSpec;
import org.apache.http.cookie.CookieSpecProvider;
import org.apache.http.protocol.HttpContext;

public class EasySpecProvider implements CookieSpecProvider {

	@Override
	public CookieSpec create(HttpContext arg0) {
		// TODO Auto-generated method stub
		return null;
	}
}

6.Check.java 測試看看有沒有成功

首先,得在D:\data\image\wjc.png這個路徑裏,也就是image文件夾裏放一張驗證碼的圖片
,隨便網上下一張驗證碼的圖片即可,不要那種肉眼難辨的文字哦!

import java.net.URISyntaxException;
import java.io.File;
import java.net.URI;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
 * 測試類
 * @author Administrator
 *
 */

@SuppressWarnings("deprecation")		  
public class Check {
    private static final String POST_URL = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=" + AuthService.getAuth();
 
    /**
     * 識別本地圖片的文字
     *
     * @param path 本地圖片地址
     * @return 識別結果,爲json格式
     * @throws URISyntaxException URI打開異常
     * @throws IOException        io流異常
     */
    public static String checkFile(String path) throws URISyntaxException, IOException {
        File file = new File(path);
        if (!file.exists()) {
            throw new NullPointerException("圖片不存在");
        }
        String image = BaseImg64.getImageStrFromPath(path);
        String param = "image=" + image;
        return post(param);
    }

    /**
     * @param url 圖片url
     * @return 識別結果,爲json格式
     */
    public static String checkUrl(String url) throws IOException, URISyntaxException {
        String param = "url=" + url;
        return post(param);
    }

    /**
     * 通過傳遞參數:url和image進行文字識別
     *
     * @param param 區分是url還是image識別
     * @return 識別結果
     * @throws URISyntaxException URI打開異常
     * @throws IOException        IO流異常
     */
    private static String post(String param) throws URISyntaxException, IOException {
        //開始搭建post請求
    	URI url = new URI(POST_URL);
    	RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();  
    	CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(globalConfig).build();  
    	HttpGet request = new HttpGet(url);  
    	      	    	
		HttpClient httpClient = new DefaultHttpClient();
        HttpPost post = new HttpPost();
        
        post.setURI(url);
        //設置請求頭,請求頭必須爲application/x-www-form-urlencoded,因爲是傳遞一個很長的字符串,不能分段發送
        post.setHeader("Content-Type", "application/x-www-form-urlencoded");
        StringEntity entity = new StringEntity(param);
        post.setEntity(entity);
        CloseableHttpResponse response = client.execute(post);
      // HttpResponse response = httpClient.execute(post);
       
      //  System.out.println(response.toString());
        if (response.getStatusLine().getStatusCode() == 200) {
            String str;
            try {
                /*讀取服務器返回過來的json字符串數據*/
                str = EntityUtils.toString(response.getEntity());
                String []result=str.split(":");
               result1 = result[4].split("\"");
               // System.out.println(result1[1]);//驗證碼結果
                System.out.println(str);//打印得到的數據
                return str;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return null;
        	 	
    }

    public static void main(String[] args) throws Exception {
    	 String  path1 = "D:\\data\\image\\wjc.png";//絕對路徑
    	                           	
        try {
            long now = System.currentTimeMillis();
            checkFile(path1);
            
           //這是測網頁上的圖片
          // checkUrl("https://images0.cnblogs.com/blog/508489/201505/101311124074020.png");
            System.out.println("耗時:" + (System.currentTimeMillis() - now) / 1000 + "s");
        } catch (URISyntaxException | IOException e) {
            e.printStackTrace();
        }
        
    }
 
   }

到此,文字識別就實現啦!

2.如何實現大圖找小圖?

直接上代碼!
請新建項目測試哦!
CoordBean.java

public class CoordBean
{
  private int x;
  private int y;

  public int getX()
  {
    return this.x;
  }

  public void setX(int x) {
    this.x = x;
  }

  public int getY()
  {
    return this.y;
  }

  public void setY(int y) {
    this.y = y;
  }
}

ImageCognition.java

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
/**
 * 圖像識別
 * @author Administrator
 *
 */
public class ImageCognition
{//精確度
  public static final int SIM_ACCURATE_VERY = 0;
  public static final int SIM_ACCURATE = 31;
  public static final int SIM_BLUR = 61;
  public static final int SIM_BLUR_VERY = 81;

  public List<CoordBean> imageSearch(BufferedImage sourceImage, BufferedImage searchImage, int sim)
  {
    List list = new ArrayList();

    RgbImageComparerBean pxSource = getPX(sourceImage);
    RgbImageComparerBean pxSearch = getPX(searchImage);

    int[][] px = pxSource.getColorArray();
    int[][] pxS = pxSearch.getColorArray();
    int pxSXMax = pxSearch.getImgWidth() - 1;
    int pxSYMax = pxSearch.getImgHeight() - 1;
    int xSearchEnd = pxSource.getImgWidth() - pxSearch.getImgWidth();
    int ySearchEnd = pxSource.getImgHeight() - pxSearch.getImgHeight();

    int contentSearchX = 1;
    int contentSearchY = 1;

    double pxPercent = 0.9900000095367432D;
    if (sim > 0)
    {
      pxPercent = sim / 255.0D / 4.0D;
    }

    for (int x = 0; x < xSearchEnd; x++) {
      for (int y = 0; y < ySearchEnd; y++)
      {
        boolean contrast = false;

        if (sim < 32)
        {
          if (colorCompare(px[x][y], pxS[0][0], sim))
          {
            int pxX = x + pxSearch.getImgWidth() - 1;
            if (colorCompare(px[pxX][y], pxS[pxSXMax][0], sim))
            {
              int pxY = y + pxSearch.getImgHeight() - 1;
              if (colorCompare(px[x][pxY], pxS[0][pxSYMax], sim))
              {
                if (colorCompare(px[pxX][pxY], 
                  pxS[pxSXMax][pxSYMax], sim))
                {
                  if (pxSXMax > 2) {
                    contentSearchX = 
                      (int)Math.ceil(pxSXMax / 2);
                  }
                  if (pxSYMax > 2) {
                    contentSearchY = 
                      (int)Math.ceil(pxSYMax / 2);
                  }

                  if (colorCompare(
                    px[(x + contentSearchX)][
                    (y + 
                    contentSearchY)], 
                    pxS[contentSearchX][contentSearchY], 
                    sim))
                  {
                    contrast = true;
                  }
                }
              }
            }
          }
        }
        else {
          contrast = true;
        }

        if (sim < 62)
        {
          if (contrast) {
            int yes = 0;

            int ySour = y + contentSearchY;
            for (int i = 0; i < pxSearch.getImgWidth(); i++)
            {
              if (colorCompare(px[(x + i)][ySour], 
                pxS[i][contentSearchY], sim)) {
                yes++;
              }
            }
            if (yes / pxSearch.getImgWidth() > pxPercent)
              contrast = true;
            else {
              contrast = false;
            }

          }

          if (contrast) {
            int yes = 0;

            int xSour = x + contentSearchX;
            for (int i = 0; i < pxSearch.getImgHeight(); i++)
            {
              if (colorCompare(px[xSour][(y + i)], 
                pxS[contentSearchX][i], sim)) {
                yes++;
              }
            }

            if (yes / pxSearch.getImgHeight() > pxPercent)
              contrast = true;
            else
              contrast = false;
          }
        }
        else
        {
          contrast = true;
        }

        if (contrast) {
          int yes = 0;
          for (int xS = 0; xS < pxSearch.getImgWidth(); xS++) {
            for (int yS = 0; yS < pxSearch.getImgHeight(); yS++)
            {
              if (colorCompare(px[(x + xS)][(y + yS)], pxS[xS][yS], 
                sim)) {
                yes++;
              }
            }
          }
          if (yes / pxSearch.getPxCount() > pxPercent) {
            CoordBean coord = new CoordBean();
            coord.setX(x);
            coord.setY(y);
            list.add(coord);
          }
        }
      }
    }

    return list;
  }

  public RgbImageComparerBean getPX(BufferedImage bufferedImage)
  {
    int width = bufferedImage.getWidth();
    int height = bufferedImage.getHeight();
    int minx = bufferedImage.getMinX();
    int miny = bufferedImage.getMinY();

    RgbImageComparerBean rgb = new RgbImageComparerBean();
    int[][] colorArray = new int[width][height];
    for (int i = minx; i < width; i++) {
      for (int j = miny; j < height; j++) {
        colorArray[i][j] = bufferedImage.getRGB(i, j);
      }
    }
    rgb.setColorArray(colorArray);
    return rgb;
  }

  public boolean colorCompare(int pxSource, int pxSearch, int sim)
  {
    if (sim == 0) {
      return pxSearch == pxSource;
    }
    Color sourceRgb = new Color(pxSource);
    Color searchRgb = new Color(pxSearch);
    return colorCompare(sourceRgb, searchRgb, sim);
  }

  public boolean colorCompare(Color color1, Color color2, int sim)
  {
    return (Math.abs(color1.getRed() - color2.getRed()) <= sim) && 
      (Math.abs(color1.getGreen() - color2.getGreen()) <= sim) && 
      (Math.abs(color1.getBlue() - color2.getBlue()) <= sim);
  }
}

RgbImageComparerBean.java

/**
 * 圖像對比
 * @author Administrator
 *
 */
public class RgbImageComparerBean
{
  private int[][] colorArray;
  private boolean[][] ignorePx;
  private int imgWidth;
  private int imgHeight;
  private int pxCount;

  public int[][] getColorArray()
  {
    return this.colorArray;
  }

  public void setPxCount(int pxCount)
  {
    this.pxCount = pxCount;
  }

  public void setColorArray(int[][] colorArray)
  {
    this.colorArray = colorArray;
    this.imgWidth = this.colorArray.length;
    this.imgHeight = this.colorArray[0].length;
    this.pxCount = (this.imgWidth * this.imgHeight);
  }

  public boolean[][] getIgnorePx()
  {
    return this.ignorePx;
  }

  public void setIgnorePx(boolean[][] ignorePx)
  {
    this.ignorePx = ignorePx;
  }

  public int getImgWidth()
  {
    return this.imgWidth;
  }

  public int getImgHeight()
  {
    return this.imgHeight;
  }

  public int getPxCount()
  {
    return this.pxCount;
  }
}

Image.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;


/**
 * 測試類
 * @author Administrator
 *
 */
public class Image {
	private static int x=0;//橫座標
	private static int y=0;//縱座標
	private static int b=1;
	public static void main(String[] args) throws Exception {
		if(!findImage4FullScreen(ImageCognition.SIM_ACCURATE_VERY)) {
			System.out.println("很抱歉...截圖裏沒找到您想要搜索的圖片呢!");
		}
		}
	}
	  /** 
     * 將字符串複製到剪切板。 
     */  
    public static void setSysClipboardText(String writeMe) {  
        Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();  
        Transferable tText = new StringSelection(writeMe);  
        clip.setContents(tText, null);  
    } 
	public static Boolean findImage4FullScreen(int sim) throws Exception {
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		int w = (int) screenSize.getWidth();//屏幕寬度
		int h=(int)screenSize.getHeight();//屏幕高度

		Robot robot = new Robot();
		//截屏操作
		BufferedImage screenImg = robot.createScreenCapture(new Rectangle(0, 0,
				w, h));
		OutputStream out = new FileOutputStream("D:\\data\\image/screen.png");
		ImageIO.write(screenImg, "png", out);//將截到的BufferedImage寫到本地
		
		InputStream in = new FileInputStream("D:\\data\\image/search.png");
		BufferedImage searchImg = ImageIO.read(in);//將要查找的本地圖讀到BufferedImage

		//圖片識別工具類
		ImageCognition ic = new ImageCognition();

		List<CoordBean> list = ic.imageSearch(screenImg, searchImg, sim);
		for (CoordBean coordBean : list) {
			System.out.println("找到您要的圖片了,它的座標是" +"(" +coordBean.getX() + ","
					+ coordBean.getY()+")");
			
			
			//標註找到的圖的位置
			Graphics g = screenImg.getGraphics();
			g.setColor(Color.BLACK);
			g.drawRect(coordBean.getX(), coordBean.getY(),
					searchImg.getWidth(), searchImg.getHeight());
			g.setFont(new Font(null, Font.BOLD, 20));
			g.drawString("←找到的圖片在這裏哦!",
					coordBean.getX() + searchImg.getWidth() + 5,
					coordBean.getY() + 10 + searchImg.getHeight() / 2);
			out = new FileOutputStream("D:\\data\\image/result.png");
			ImageIO.write(screenImg, "png", out);
			x=coordBean.getX() ;
			y=coordBean.getY();
			return true;
		}
		return false;
	}
}

測試方法:
在這裏插入圖片描述
在上圖的路徑分別截屏小圖,就是屏幕的某一個位置的小圖,名爲search.png
再截全屏,名爲screen.png,然後運行一下Image .java,就會生成一個result.png啦!

3.那麼問題來了,怎麼實現識別驗證碼並自動提交?

把代碼整合起來就好啦!

打字有點累…休息下…

(1)先來說說如何模擬鼠標動作吧!

Robot robot = new Robot();
robot.delay(100);
robot.mouseMove(x+20, y+20);//鼠標移動到該座標
robot.delay(100);
//鼠標點擊
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
robot.delay(100);
//鼠標釋放
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);

(2)怎麼把一個字符串複製到電腦的剪貼板上呢?

 /** 
     * 將字符串複製到剪切板。 
     */  
    public static void setSysClipboardText(String writeMe) {  
        Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();  
        Transferable tText = new StringSelection(writeMe);  
        clip.setContents(tText, null);  
    } 

(3)又怎麼模擬鍵盤動作呢粘貼字符串?

 robot.keyPress(KeyEvent.VK_CONTROL);
 robot.keyPress(KeyEvent.VK_V);
 robot.delay(10);
 robot.keyRelease(KeyEvent.VK_CONTROL);
 robot.keyRelease(KeyEvent.VK_V);
 robot.keyPress(KeyEvent.VK_ENTER);
 robot.delay(10);
 robot.keyRelease(KeyEvent.VK_ENTER);

(4)全部的代碼整合:

1.留下以下這些類,把剛纔的Image .java刪掉,它已經沒有價值 了。
在這裏插入圖片描述
2.修改Check.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Random;
import javax.imageio.ImageIO;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
/**
 * 測試類
 * @author Administrator
 *
 */

@SuppressWarnings("deprecation")		  //https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic
public class Check {
    private static final String POST_URL = "https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=" + AuthService.getAuth();
    private static int x=0;//橫座標
	private static int y=0;//縱座標
	private static String result1[]=new String[1000];
    /**
     * 識別本地圖片的文字
     *
     * @param path 本地圖片地址
     * @return 識別結果,爲json格式
     * @throws URISyntaxException URI打開異常
     * @throws IOException        io流異常
     */
    public static String checkFile(String path) throws URISyntaxException, IOException {
        File file = new File(path);
        if (!file.exists()) {
            throw new NullPointerException("圖片不存在");
        }
        String image = BaseImg64.getImageStrFromPath(path);
        String param = "image=" + image;
        return post(param);
    }

    /**
     * @param url 圖片url
     * @return 識別結果,爲json格式
     */
    public static String checkUrl(String url) throws IOException, URISyntaxException {
        String param = "url=" + url;
        return post(param);
    }

    /**
     * 通過傳遞參數:url和image進行文字識別
     *
     * @param param 區分是url還是image識別
     * @return 識別結果
     * @throws URISyntaxException URI打開異常
     * @throws IOException        IO流異常
     */
    private static String post(String param) throws URISyntaxException, IOException {
        //開始搭建post請求
    	URI url = new URI(POST_URL);
    	RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();  
    	CloseableHttpClient client = HttpClients.custom().setDefaultRequestConfig(globalConfig).build();  
    	HttpGet request = new HttpGet(url);  
    	      	    	
		HttpClient httpClient = new DefaultHttpClient();
        HttpPost post = new HttpPost();
        
        post.setURI(url);
        //設置請求頭,請求頭必須爲application/x-www-form-urlencoded,因爲是傳遞一個很長的字符串,不能分段發送
        post.setHeader("Content-Type", "application/x-www-form-urlencoded");
        StringEntity entity = new StringEntity(param);
        post.setEntity(entity);
        CloseableHttpResponse response = client.execute(post);
      // HttpResponse response = httpClient.execute(post);
       
      //  System.out.println(response.toString());
        if (response.getStatusLine().getStatusCode() == 200) {
            String str;
            try {
                /*讀取服務器返回過來的json字符串數據*/
                str = EntityUtils.toString(response.getEntity());
                //對讀取到的字符串進行切割
                String []result=str.split(":");
               result1 = result[4].split("\"");
               // System.out.println(result1[1]);//驗證碼結果
              //  System.out.println(str);
                return str;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        return null;   	 	
    }
    public static void main(String[] args) throws Exception {
    	 String  path1 = "D:\\data\\image\\wjc.png";
    	                           	
        try {
            long now = System.currentTimeMillis();
            /**
             * 1.在check之前,要先對驗證碼截圖保存,再截全屏對比得到驗證碼的座標,從而之後才能不停地對驗證碼進行截圖,我就不做示範了!
             * 2.假裝驗證碼的圖片是每一次都不一樣的,然後去實現自動填寫提交。
             * 3.找驗證碼座標的原理是和找提交框、提交按鈕等一樣的,模仿即可!!!
             */
            checkFile(path1);
           
          // checkUrl("https://images0.cnblogs.com/blog/508489/201505/101311124074020.png");
            System.out.println("耗時:" + (System.currentTimeMillis() - now) / 1000 + "s");
        } catch (URISyntaxException | IOException e) {
            e.printStackTrace();
        }
        
        if(!findImage4FullScreen(ImageCognition.SIM_ACCURATE_VERY)) {
 			System.out.println("很抱歉...截圖裏沒找到您想要搜索的圖片呢!");
 		}else {

 			Robot robot = new Robot();
 			Random random = new Random();
 			int a = 0;
 			robot.delay(100);
 			
 			robot.mouseMove(x+30, y+30);//鼠標移動到該座標
 			a = Math.abs(random.nextInt())%100+50;
 			robot.delay(a);
 			//鼠標點擊
 			robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
 			a = Math.abs(random.nextInt())%50+50;
 			robot.delay(a);
 			robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
 			
 			String res=result1[1].toString();
 			System.out.println(res);
 			setSysClipboardText(res);
 		    robot.keyPress(KeyEvent.VK_CONTROL);
 		    robot.keyPress(KeyEvent.VK_V);
 		    robot.delay(10);
 		    robot.keyRelease(KeyEvent.VK_CONTROL);
 		    robot.keyRelease(KeyEvent.VK_V);
 		    robot.keyPress(KeyEvent.VK_ENTER);
 		   robot.delay(10);
 		   robot.keyRelease(KeyEvent.VK_ENTER);
 			
 		}
        
    }
    /** 
     * 將字符串複製到剪切板。 
     */  
    public static void setSysClipboardText(String writeMe) {  
        Clipboard clip = Toolkit.getDefaultToolkit().getSystemClipboard();  
        Transferable tText = new StringSelection(writeMe);  
        clip.setContents(tText, null);  
    } 

/**
 * 大圖找小圖    
 * @param sim
 * @return
 * @throws Exception
 */
    public static Boolean findImage4FullScreen(int sim) throws Exception {
		Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
		int w = (int) screenSize.getWidth();//屏幕寬度
		int h=(int)screenSize.getHeight();//屏幕高度

		Robot robot = new Robot();
		//截屏操作
		BufferedImage screenImg = robot.createScreenCapture(new Rectangle(0, 0,
				w, h));
		OutputStream out = new FileOutputStream("D:\\data\\image\\screen.png");
		ImageIO.write(screenImg, "png", out);//將截到的BufferedImage寫到本地
		
		InputStream in = new FileInputStream("D:\\data\\image\\search.png");
		BufferedImage searchImg = ImageIO.read(in);//將要查找的本地圖讀到BufferedImage

		//圖片識別工具類
		ImageCognition ic = new ImageCognition();

		List<CoordBean> list = ic.imageSearch(screenImg, searchImg, sim);
		for (CoordBean coordBean : list) {
			System.out.println("找到圖片了,它的座標是" +"(" +coordBean.getX() + ","
					+ coordBean.getY()+")");
					
			//標註找到的圖的位置
			Graphics g = screenImg.getGraphics();
			g.setColor(Color.BLACK);
			g.drawRect(coordBean.getX(), coordBean.getY(),
					searchImg.getWidth(), searchImg.getHeight());
			g.setFont(new Font(null, Font.BOLD, 20));
			g.drawString("←找到的圖片在這裏",
					coordBean.getX() + searchImg.getWidth() + 5,
					coordBean.getY() + 10 + searchImg.getHeight() / 2);
			out = new FileOutputStream("D:\\data\\image\\result.png");
			ImageIO.write(screenImg, "png", out);
			x=coordBean.getX() ;
			y=coordBean.getY();
			return true;
		}
		return false;
	}
    }

(5)關於整合代碼之後怎麼測試?

這個也很好測試,可以在桌面新建個TXT文檔,根據我以上的思路,讓它自己寫東西,很好很好…

有不懂的可以留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章