网易易盾验证码是一种常见的滑动拼图验证码,通过模拟用户行为完成验证。本文将介绍如何使用Java、Selenium和OpenCV破解网易易盾滑动验证码。我们将详细解释每一步的代码逻辑,以确保你可以直接运行和理解这些代码。
环境准备
在开始之前,请确保已安装以下工具和库:
Java Development Kit (JDK)
Selenium WebDriver
OpenCV库
适用于浏览器的驱动程序(如ChromeDriver)
下载并配置这些工具,以便能够编写和运行Java代码。
下载OpenCV库
前往OpenCV官方网站下载适用于你的操作系统的OpenCV库,并将其解压到本地目录。
配置Java项目
在你的Java项目中,引入Selenium和OpenCV的库文件。以下是pom.xml的示例配置(使用Maven):
xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>captcha-solver</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.opencv</groupId>
<artifactId>opencv</artifactId>
<version>4.5.5-0</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
</project>
破解验证码的步骤
1. 加载OpenCV库
在Java中加载OpenCV库:
java
public class CaptchaSolver {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
}
2. 获取验证码图片
通过Selenium获取滑动验证码的背景图和滑块图:
java
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class CaptchaSolver {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) throws IOException {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("https://dun.163.com/trial/jigsaw");
WebElement bgImageElement = driver.findElement(By.cssSelector(".yidun_bg-img"));
WebElement sliderImageElement = driver.findElement(By.cssSelector(".yidun_jigsaw"));
String bgImageUrl = bgImageElement.getAttribute("src");
String sliderImageUrl = sliderImageElement.getAttribute("src");
File bgImageFile = new File("bg.png");
File sliderImageFile = new File("slider.png");
FileUtils.copyURLToFile(new URL(bgImageUrl), bgImageFile);
FileUtils.copyURLToFile(new URL(sliderImageUrl), sliderImageFile);
// 下一步:计算滑动距离
}
}
3. 使用OpenCV计算滑动距离
通过模板匹配计算滑动距离:
java
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
public class CaptchaSolver {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) throws IOException {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("https://dun.163.com/trial/jigsaw");
WebElement bgImageElement = driver.findElement(By.cssSelector(".yidun_bg-img"));
WebElement sliderImageElement = driver.findElement(By.cssSelector(".yidun_jigsaw"));
String bgImageUrl = bgImageElement.getAttribute("src");
String sliderImageUrl = sliderImageElement.getAttribute("src");
File bgImageFile = new File("bg.png");
File sliderImageFile = new File("slider.png");
FileUtils.copyURLToFile(new URL(bgImageUrl), bgImageFile);
FileUtils.copyURLToFile(new URL(sliderImageUrl), sliderImageFile);
double distance = getDistance("bg.png", "slider.png");
System.out.println("滑动距离: " + distance);
// 下一步:模拟滑动行为
}
public static double getDistance(String bgPath, String sliderPath) {
Mat bgMat = Imgcodecs.imread(bgPath);
Mat sliderMat = Imgcodecs.imread(sliderPath);
// 转灰度图像
Mat graySliderMat = new Mat();
Imgproc.cvtColor(sliderMat, graySliderMat, Imgproc.COLOR_BGR2GRAY);
// 二值化图像
Mat binarySliderMat = new Mat();
Imgproc.threshold(graySliderMat, binarySliderMat, 127, 255, Imgproc.THRESH_BINARY);
// 模板匹配
int resultCols = bgMat.cols() - sliderMat.cols() + 1;
int resultRows = bgMat.rows() - sliderMat.rows() + 1;
Mat result = new Mat(resultRows, resultCols, CvType.CV_32FC1);
Imgproc.matchTemplate(bgMat, sliderMat, result, Imgproc.TM_SQDIFF);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
MinMaxLocResult mmr = Core.minMaxLoc(result);
Point matchLoc = mmr.minLoc;
return matchLoc.x;
}
}
4. 模拟滑动行为
模拟滑动行为以实现破解效果:
java
import org.openqa.selenium.interactions.Actions;
public class CaptchaSolver {
// ...其他代码...
public static void main(String[] args) throws IOException, InterruptedException {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("https://dun.163.com/trial/jigsaw");
WebElement bgImageElement = driver.findElement(By.cssSelector(".yidun_bg-img"));
WebElement sliderImageElement = driver.findElement(By.cssSelector(".yidun_jigsaw"));
String bgImageUrl = bgImageElement.getAttribute("src");
String sliderImageUrl = sliderImageElement.getAttribute("src");
File bgImageFile = new File("bg.png");
File sliderImageFile = new File("slider.png");
FileUtils.copyURLToFile(new URL(bgImageUrl), bgImageFile);
FileUtils.copyURLToFile(new URL(sliderImageUrl), sliderImageFile);
double distance = getDistance("bg.png", "slider.png");
System.out.println("滑动距离: " + distance);
move(driver, sliderImageElement, (int) distance);
// 下一步:验证结果
}
public static void move(WebDriver driver, WebElement element, int distance) throws InterruptedException {
int randomTime = 0;
if (distance > 90) {
randomTime = 250;
} else if (distance > 80 && distance <= 90) {
randomTime = 150;
}
List<Integer> track = getMoveTrack(distance - 2);
int moveY = 1;
try {
Actions actions = new Actions(driver);
actions.clickAndHold(element).perform();
Thread.sleep(200);
for (int i : track) {
actions.moveByOffset(i, moveY).perform();
Thread.sleep(new Random().nextInt(300) + randomTime);
}
Thread.sleep(200);
actions.release(element).perform();
} catch (Exception e) {
e.printStackTrace();
}
}
public static List<Integer> getMoveTrack(int distance) {
List<Integer> track = new ArrayList<>();
Random random = new Random();
int current = 0;
int mid = (int) distance * 4 / 5;
int a = 0;
int move = 0;
while (true) {
a = random.nextInt(10);
if (current <= mid) {
move += a;
} else {
move -= a;
}
if ((current + move) < distance) {
track.add(move);
} else {
track.add(distance - current);
break;
}
current += move;
}
return track;
}
}
更多内容联系q1436423940