两个文件的主要目的是通过 Selenium、ChromeDriver 和 OpenCV 来实现自动化解决滑块验证码的问题。滑块验证码通常要求用户拖动一个滑块到正确的位置,以验证用户是否为真人。
下面我将详细讲解这两个文件的工作流程和具体功能的原理。
1. cvdemo.java 文件
这个文件主要包含了一个使用 OpenCV 进行图像处理的方法 getPos,用于检测滑块图像中目标区域的位置。
1.1 工作流程
- 加载 OpenCV 库:
java
static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }
这段代码加载了 OpenCV 的本地库,确保后续的 OpenCV 函数可以正常调用。
- 读取图像:
java
Mat image = Imgcodecs.imread(imageSrc);
通过 Imgcodecs.imread 方法读取指定路径的图像文件,返回一个 Mat 对象(OpenCV 中用于存储图像数据的矩阵)。
- 高斯模糊:
java
Imgproc.GaussianBlur(image, blurred, new Size(5, 5), 0, 0);
使用高斯模糊对图像进行平滑处理,减少图像中的噪声,便于后续的边缘检测。
- Canny 边缘检测:
java
Imgproc.Canny(blurred, canny, 0, 100);
使用 Canny 边缘检测算法检测图像中的边缘。Canny 算法能够有效地检测出图像中的边缘,便于后续的轮廓检测。
- 查找轮廓:
java
Imgproc.findContours(canny, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);
通过 findContours 方法查找图像中的轮廓,并将轮廓存储在 contours 列表中。
- 遍历轮廓并筛选目标区域:
javascript
for (MatOfPoint contour : contours) { Rect rect = Imgproc.boundingRect(contour); double area = Imgproc.contourArea(contour); double zhouchang = Imgproc.arcLength(contour2f, true); if (1500 < area && area < 5000 && 100 < zhouchang && zhouchang < 500) { // 绘制矩形并保存图像 Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), new Scalar(0, 0, 255), 2); Imgcodecs.imwrite("111.jpg", image); return rect.x; } }
遍历所有轮廓,计算每个轮廓的面积和周长,筛选出符合特定条件的轮廓(即滑块的目标区域)。如果找到符合条件的轮廓,绘制矩形并保存图像,最后返回目标区域的横坐标 rect.x。
1.2 功能原理
- 图像处理:通过高斯模糊和 Canny 边缘检测,提取图像中的边缘信息。
- 轮廓检测:通过 findContours 方法找到图像中的轮廓,并通过面积和周长筛选出目标区域。
- 目标定位:返回目标区域的横坐标,用于后续的滑块拖动操作。
2. numbertest.java 文件
这个文件主要使用 Selenium 和 ChromeDriver 自动化操作浏览器,并结合 OpenCV处理滑块验证码。
2.1 工作流程
- 初始化 ChromeDriver:
java
System.getProperties().setProperty("webdriver.chrome.driver",
"D:\\chromedriverdemo\\chromedriver.exe"); ChromeDriver chromeDriver = new ChromeDriver();
设置 ChromeDriver 的路径并初始化 ChromeDriver 对象,用于控制 Chrome 浏览器。
- 访问目标网站:
java
chromeDriver.get("https://www.lagou.com/wn/");
打开目标网站(拉勾网)。
- 点击登录按钮:
java
WebElement loginDiv = chromeDriver.findElement(By.className("btn__1GVMf"));
JavascriptExecutor jsExecutor = (JavascriptExecutor) chromeDriver;
jsExecutor.executeScript("arguments[0].click();", loginDiv);
使用 JavaScriptExecutor 点击登录按钮,弹出登录窗口。
- 输入手机号并点击获取验证码:
java
WebElement inputNum = chromeDriver.findElement(By.name("phone-account"));
inputNum.sendKeys(phone); WebElement sendNum =chromeDriver.findElement(By.cssSelector(".ant-btn.ant-btn-link"));
sendNum.click();
自动输入手机号并点击获取验证码按钮,触发滑块验证码的显示。
- 获取滑块验证码图片的 URL:
java
WebElement pic = chromeDriver.findElement(By.cssSelector("body > div:nth-of-type(4) > div > div > div:nth-child(2) > div > div > div > div:nth-child(2)"));
String style = pic.getAttribute("style");
Pattern pattern = Pattern.compile("url\\(\"([^\"]+)\"");
Matcher matcher = pattern.matcher(style);
String fileURL = matcher.group(1);
通过正则表达式从滑块验证码图片的 style 属性中提取图片的 URL。
下载滑块验证码图片:
java
URL url = new URL(fileURL);
try (InputStream in = url.openStream();
FileOutputStream out = new FileOutputStream(saveDir)) { byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead);
} }
将滑块验证码图片下载到本地。
getPos 方法获取滑块目标位置:
java
int left = getPos(saveDir);
调用 getPos 方法处理滑块验证码图片,获取目标区域的横坐标。
- 模拟拖动滑块:
java
WebElement movBox = chromeDriver.findElement(By.cssSelector("body > div:nth-of-type(4) > div > div > div:nth-child(2) > div > div > div > div:nth-child(1) > div:nth-child(1)"));
Actions actions = new Actions(chromeDriver);
actions.clickAndHold(movBox).perform();
while (moved < left - 6) { x = random.nextInt(10); moved += x;
actions.moveByOffset(x, 0).perform();
} actions.release().perform();
使用 Selenium 的 Actions 类模拟拖动滑块到目标位置。
2.2 功能原理
- 自动化操作浏览器:通过 Selenium 和 ChromeDriver 自动化操作浏览器,模拟用户点击、输入等操作。
- 图像处理:通过 OpenCV 处理滑块验证码图片,定位目标区域。
- 模拟拖动滑块:通过 Selenium 的 Actions 类模拟拖动滑块到目标位置,完成验证码的验证。
3. 总结
- cvdemo.java:主要负责图像处理,通过 OpenCV 检测滑块验证码中的目标区域,并返回目标区域的横坐标。
- numbertest.java:主要负责自动化操作浏览器,结合图像处理的结果,模拟用户拖动滑块完成验证码的验证。
这两个文件通过结合 Selenium、ChromeDriver和 OpenCV,实现了自动化解决滑块验证码的功能。