一、使用的技術:
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;
}
}
- 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文檔,根據我以上的思路,讓它自己寫東西,很好很好…
有不懂的可以留言。