準備
本地Chrome版本對應WebDriver驅動:http://chromedriver.storage.googleapis.com/index.html
maven包
<!-- selenium-->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.9.0</version>
</dependency>
思路
1、獲取背景圖片元素
WebElement bimg= webDriver.findElement(By.xpath(""));
xpath:f12定位背景圖片元素右鍵copy--->Copy Xpath
截圖指定元素將圖片下載到本地,這里之所以不通過url獲取圖片是因為圖片大小與圖片在頁面實際大小可能并不一致,我們需要操作頁面所以以頁面為準,
File bFile = new File("C:\\Users\\jyk\\Desktop\\bFile.jpg");
FileTool.screenshotsWebElement(bimg, bFile);
/**
* 元素截圖
* @param webElement
* @param out
* @throws IOException
*/
public static void screenshotsWebElement(WebElement webElement, File out) throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
File screenshotAs = webElement.getScreenshotAs(OutputType.FILE);
//讀取檔案
fis = new FileInputStream(screenshotAs);
int available = fis.available();
byte[] bytes = new byte[available];
fis.read(bytes);
//輸出檔案
fos = new FileOutputStream(out);
fos.write(bytes);
fis.close();
fos.close();
}
定義正則,難點之一,需要自己去找規律設定對應的正則
//正則 //101,010 String z1 = "01{54}0"; String z2 = "10{54}1"; //11000011,兩端短中間長 String z3 = "1{1,5}0{45,54}1{1,5}"; String z4 = "0{1,5}1{45,54}0{1,5}"; //0000000011100000000,兩端長中間短 String z5 = "1{5,}0{1,45}1{5,}"; String z6 = "0{5,}1{1,45}0{5,}"; //01*10 String z7 = "10【0-1】{52}01"; String z8 = "01【0-1】{52}10"; List<String> zs = new ArrayList<>(); zs.add(z1); zs.add(z2); zs.add(z3); zs.add(z4); zs.add(z5); zs.add(z6); zs.add(z7); zs.add(z8); List<Pattern> patterns = new ArrayList<>(); for (String z : zs) { Pattern pattern = Pattern.compile(z); patterns.add(pattern); }
決議圖片

BufferedImage bgBI = ImageIO.read(bFile);
//獲取圖片長寬
int minX = bgBI.getMinX();
int maxX = bgBI.getWidth();
int minY = bgBI.getMinY();
int maxY = bgBI.getHeight();
StringBuilder sb = new StringBuilder();
//對每一個像素二值化處理
for (int Y = minY; Y < maxY; Y++) {
for (int X = minX; X < maxX; X++) {
int rgb = bgBI.getRGB(X, Y);
Color col = new Color(rgb, true);
int r = col.getRed();
int g = col.getGreen();
int b = col.getBlue();
int threshold = (r + g + b) / 3;
//顏色范圍為0-255,取中為閾值
if (threshold > 125) {
sb.append(0);
} else {
sb.append(1);
}
}
for (Pattern p : patterns) {
int index = 0;
Matcher matcher = p.matcher(sb);
boolean find = matcher.find();
if (find) {
index = matcher.start();
}
if (index > 80) {
Integer count = indexMap.get(index);
if (count != null) {
indexMap.put(index, (count + 1));
} else {
indexMap.put(index, 1);
}
}
}
// System.out.println(sb);
sb.delete(0, sb.length());
}
二值化處理后

2、定位
難點為如何告訴計算機陰影位置,
思路------肉眼之所以能判斷出陰影位置是因為陰影位置色差小,并且存在邊緣線條,所以通過二值化處理后陰影所在區域必然有大量相似資料,且邊緣資料相同y(豎著的1或0)
以下面兩個正則為例:通過觀察發現存在大量以1、0開頭結尾長度為56的資料
通過一行一行正則匹配,陰影所在位置x(橫)是不變的,只有y(豎)是變化的,累積x的權重,x為橫向所以等于偏移量
String z1 = "01{54}0";
String z2 = "10{54}1";
//代碼片段,僅講解,不可直接復制
//計數
Map<Integer, Integer> indexMap = new HashMap<>();
for (Pattern p : patterns) {
int index = 0;
Matcher matcher = p.matcher(sb);
boolean find = matcher.find();
if (find) {
index = matcher.start();
}
if (index > 80) {
Integer count = indexMap.get(index);
if (count != null) {
indexMap.put(index, (count + 1));
} else {
indexMap.put(index, 1);
}
}
}
int k = 0;
int v = 0;
Iterator<Map.Entry<Integer, Integer>> iterator = indexMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, Integer> next = iterator.next();
if (next.getValue() > v) {
v = next.getValue();
k = next.getKey();
}
}
System.out.println(k);
3、模擬拖拽
//模擬軌跡
//獲取滑塊元素
WebElement himg= webDriver.findElement(By.xpath(""));
Actions actions = new Actions(webDriver); actions.clickAndHold(himg); for (int i = 0; i < 10; i++) { actions.moveByOffset(k / 10, 0); Thread.sleep(100); } actions.moveByOffset(40, 0); Thread.sleep(200); actions.moveByOffset(-40, 0); Thread.sleep(200);
//這里多出的20是滑塊大小需要自行調整 actions.moveByOffset(20, 0); actions.release(himg).perform();
本地可測驗代碼
spring boot環境
下載上面的圖片,保存到本地進行測驗,其它圖片可以自己從新定義正則運算式,
聯網代碼因為每個網站都不一樣就不發了,提供思路
1、加載驅動、打開網址
2、點擊驗證獲取背景圖片
3、決議圖片獲取偏移量:主要難點在需要找規律、從而定義正則運算式
4、獲取滑塊元素,模擬拖拽
@Test
void testimg3() throws IOException {
File bFile = new File("本地圖片地址");
//正則
//101,010
String z1 = "0{1}1{54}0";
String z2 = "1{1}0{54}1";
//11000011,兩端短中間長
String z3 = "1{1,5}0{45,54}1{1,5}";
String z4 = "0{1,5}1{45,54}0{1,5}";
//0000000011100000000,兩端長中間短
String z5 = "1{5,}0{1,45}1{5,}";
String z6 = "0{5,}1{1,45}0{5,}";
//01*10
String z7 = "10【0-1】{52}01";
String z8 = "01【0-1】{52}10";
List<String> zs = new ArrayList<>();
zs.add(z1);
zs.add(z2);
zs.add(z3);
zs.add(z4);
zs.add(z5);
zs.add(z6);
zs.add(z7);
zs.add(z8);
List<Pattern> patterns = new ArrayList<>();
for (String z : zs) {
Pattern pattern = Pattern.compile(z);
patterns.add(pattern);
}
//計數
Map<Integer, Integer> indexMap = new HashMap<>();
//決議圖片
BufferedImage bgBI = ImageIO.read(bFile);
int minX = bgBI.getMinX();
int maxX = bgBI.getWidth();
int minY = bgBI.getMinY();
int maxY = bgBI.getHeight();
StringBuilder sb = new StringBuilder();
for (int Y = minY; Y < maxY; Y++) {
for (int X = minX; X < maxX; X++) {
int rgb = bgBI.getRGB(X, Y);
Color col = new Color(rgb, true);
int r = col.getRed();
int g = col.getGreen();
int b = col.getBlue();
//像素平均值
int threshold = (r + g + b) / 3;
//顏色范圍0-255,取中為閾值進行二值化
if (threshold > 125) {
sb.append(0);
} else {
sb.append(1);
}
}
//進行正則匹配累計權重
for (Pattern p : patterns) {
int index = 0;
Matcher matcher = p.matcher(sb);
boolean find = matcher.find();
if (find) {
index = matcher.start();
}
//80為滑塊大小、排除滑塊
if (index > 80) {
Integer count = indexMap.get(index);
if (count != null) {
indexMap.put(index, (count + 1));
} else {
indexMap.put(index, 1);
}
}
}
//輸出一行圖片像素,復制控制臺輸出資料到文本,縮小文本觀察規律
System.out.println(sb);
sb.delete(0, sb.length());
}
int k = 0;
int v = 0;
Iterator<Map.Entry<Integer, Integer>> iterator = indexMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, Integer> next = iterator.next();
if (next.getValue() > v) {
v = next.getValue();
k = next.getKey();
}
}
//偏移量,可用qq截圖判斷陰影邊緣到左側邊緣距離是否準確
System.out.println(k);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/471744.html
標籤:Java
