目标
本节的目标是使用 Java 语言实现点触验证码的识别与验证,不依赖第三方验证码识别平台。
准备工作
我们将使用 Selenium 库来驱动 Chrome 浏览器,并借助一些图像处理库来进行验证码识别。在此之前,请确保已正确安装了 Selenium 库、Chrome 浏览器,并配置好了 ChromeDriver。
了解点触验证码更多内容联系1436423940
点触验证码是一种需要点击图像中指定区域来完成验证的方式。常见的点触验证码样式如下图所示:
识别思路
识别此类验证码的难点主要在于文字和图像的识别。我们将使用 OCR 技术结合图像处理算法,来识别验证码中的文字和目标区域。
实现步骤
1. 导入依赖
在项目的 pom.xml 文件中添加以下依赖:
xml
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.bytedeco</groupId>
<artifactId>javacv-platform</artifactId>
<version>1.5.6</version>
</dependency>
</dependencies>
2. 初始化 WebDriver
java
复制代码
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
public class CaptchaSolver {
private static final String CHROME_DRIVER_PATH = "/path/to/chromedriver";
private static final String URL = "http://admin.touclick.com/login.html";
private WebDriver driver;
private WebDriverWait wait;
public CaptchaSolver() {
System.setProperty("webdriver.chrome.driver", CHROME_DRIVER_PATH);
ChromeOptions options = new ChromeOptions();
driver = new ChromeDriver(options);
wait = new WebDriverWait(driver, Duration.ofSeconds(20));
}
public void openPage() {
driver.get(URL);
}
public void login(String email, String password) {
WebElement emailField = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("email")));
WebElement passwordField = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("password")));
emailField.sendKeys(email);
passwordField.sendKeys(password);
}
public void close() {
driver.quit();
}
}
3. 获取验证码图像
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class CaptchaSolver {
// ... previous code ...
public File captureCaptcha() throws IOException {
WebElement captchaElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.className("touclick-pub-content")));
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
File captchaFile = new File("captcha.png");
FileUtils.copyFile(screenshot, captchaFile);
return captchaFile;
}
public static void main(String[] args) {
CaptchaSolver solver = new CaptchaSolver();
solver.openPage();
solver.login("your-email@example.com", "your-password");
try {
File captcha = solver.captureCaptcha();
// TODO: Implement OCR and image processing to solve captcha
} catch (IOException e) {
e.printStackTrace();
} finally {
solver.close();
}
}
}
4. 识别验证码文字和点击
为了进行验证码的识别,我们可以使用 Tesseract OCR 和 OpenCV。以下是一个简单的示例,演示如何使用这些工具:
java
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.lept.PIX;
import org.bytedeco.javacpp.tesseract.TessBaseAPI;
import org.bytedeco.opencv.opencv_core.Mat;
import org.bytedeco.opencv.opencv_imgcodecs;
import java.util.ArrayList;
import java.util.List;
public class CaptchaSolver {
// ... previous code ...
public List<int[]> recognizeText(File imageFile) {
List<int[]> coordinates = new ArrayList<>();
TessBaseAPI tessBaseAPI = new TessBaseAPI();
if (tessBaseAPI.Init("tessdata", "eng") != 0) {
System.err.println("Could not initialize tesseract.");
return coordinates;
}
PIX image = lept.pixRead(imageFile.getAbsolutePath());
tessBaseAPI.SetImage(image);
BytePointer outText = tessBaseAPI.GetUTF8Text();
String text = outText.getString();
System.out.println("OCR output: " + text);
// TODO: Implement logic to extract coordinates from text
// Dummy coordinates for demonstration
coordinates.add(new int[]{100, 200});
coordinates.add(new int[]{150, 250});
outText.deallocate();
tessBaseAPI.End();
return coordinates;
}
public void clickCaptcha(List<int[]> coordinates) {
WebElement captchaElement = wait.until(ExpectedConditions.presenceOfElementLocated(By.className("touclick-pub-content")));
Actions actions = new Actions(driver);
for (int[] coordinate : coordinates) {
actions.moveToElement(captchaElement, coordinate[0], coordinate[1]).click().perform();
try {
Thread.sleep(1000); // pause between clicks
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CaptchaSolver solver = new CaptchaSolver();
solver.openPage();
solver.login("your-email@example.com", "your-password");
try {
File captcha = solver.captureCaptcha();
List<int[]> coordinates = solver.recognizeText(captcha);
solver.clickCaptcha(coordinates);
} catch (IOException e) {
e.printStackTrace();
} finally {
solver.close();
}
}
}