滑动验证码是一种常见的验证码类型,通过拖动滑块将缺失的拼图块对准原图中的空缺位置来验证用户的操作。本文将介绍如何使用OpenCV进行模板匹配,再结合Java和Selenium实现自动化破解滑动验证码的过程。
所需技术 更多内容联系1436423940
OpenCV模板匹配:用于识别滑块在背景图中的正确位置。
Java:主要编程语言。
Selenium:用于浏览器自动化,模拟用户操作。
破解过程概述
获取验证码图像:
下载背景图和滑块图。
进行必要的图像预处理。
模板匹配:
使用OpenCV的模板匹配算法,计算滑块在背景图中的最佳匹配位置。
模拟滑动:
生成模拟人类滑动的轨迹,避免被识别为机器人。
使用Selenium模拟滑动操作。
实现步骤
1. 获取并预处理验证码图像
首先,下载验证码的背景图和滑块图,并对图像进行预处理,包括裁剪和调整亮度。
java
public static String dllPath = "C://chrome//opencv_java440.dll";
public double getDistance(String bUrl, String sUrl) {
System.load(dllPath);
try {
FileUtils.copyURLToFile(new URL(bUrl), new File("C:/EasyDun_b.png"));
FileUtils.copyURLToFile(new URL(sUrl), new File("C:/EasyDun_s.png"));
BufferedImage bgBI = ImageIO.read(new File("C:/EasyDun_b.png"));
BufferedImage sBI = ImageIO.read(new File("C:/EasyDun_s.png"));
cropImage(bgBI, sBI, new File("C:/EasyDun_b.png"), new File("C:/EasyDun_s.png"));
Mat s_mat = Imgcodecs.imread("C:/EasyDun_s.png");
Mat b_mat = Imgcodecs.imread("C:/EasyDun_b.png");
Mat s_newMat = new Mat();
Imgproc.cvtColor(s_mat, s_newMat, Imgproc.COLOR_BGR2GRAY);
binaryzation(s_newMat);
// 模板匹配
int result_rows = b_mat.rows() - s_mat.rows() + 1;
int result_cols = b_mat.cols() - s_mat.cols() + 1;
Mat g_result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
Imgproc.matchTemplate(b_mat, s_newMat, g_result, Imgproc.TM_SQDIFF);
Core.normalize(g_result, g_result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Point matchLocation = Core.minMaxLoc(g_result).maxLoc;
return matchLocation.x + s_mat.cols() - sBI.getWidth() + 12;
} catch (Throwable e) {
e.printStackTrace();
return 0;
} finally {
new File("C:/EasyDun_b.png").delete();
new File("C:/EasyDun_s.png").delete();
}
}
在上述代码中,我们加载OpenCV库,并下载并读取验证码图像。通过裁剪和亮度调整,确保图像清晰可用。
2. 模板匹配
使用OpenCV的模板匹配算法来确定滑块在背景图中的正确位置。
java
Mat g_result = new Mat();
Imgproc.matchTemplate(b_mat, s_newMat, g_result, Imgproc.TM_SQDIFF); // 根据背景颜色选择匹配算法
Core.normalize(g_result, g_result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
Point matchLocation = Core.minMaxLoc(g_result).maxLoc;
在这里,我们使用TM_SQDIFF算法进行匹配,并找到最佳匹配位置的坐标。
3. 模拟滑动操作
通过生成一条模拟人类滑动的轨迹,并使用Selenium模拟滑动操作。
java
复制代码
public static void move(WebDriver driver, WebElement element, int distance) throws InterruptedException {
List<Integer> track = getMoveTrack(distance - 2);
Actions actions = new Actions(driver);
actions.clickAndHold(element).perform();
Thread.sleep(200);
for (int move : track) {
actions.moveByOffset(move, 1).perform();
Thread.sleep(new Random().nextInt(300));
}
Thread.sleep(200);
actions.release(element).perform();
}
public static List<Integer> getMoveTrack(int distance) {
List<Integer> track = new ArrayList<>();
int current = 0;
int mid = distance * 4 / 5;
int a, move;
Random random = new Random();
while (current < distance) {
a = random.nextInt(10);
move = current <= mid ? a : -a;
if (current + move > distance) {
move = distance - current;
}
track.add(move);
current += move;
}
return track;
}