1. 本节目标
本节我们的目标是通过编写程序实现对点触验证码的自动识别和验证。
2. 准备工作
我们将使用 Java 的 Selenium 库和 Chrome 浏览器来实现目标。在开始之前,请确保您已经安装好了 Selenium 库和 Chrome 浏览器,并配置好了 ChromeDriver。相关的安装和配置步骤请参考之前的章节。
3. 了解点触验证码
点触验证码是一种需要用户点击特定位置进行验证的验证码形式。类似于 12306 网站的验证码,需要点击图像中的特定文字或图案。由于验证码的复杂性和多样性,图像识别的难度较大。为了实现自动化,我们将借助第三方验证码识别服务。
4. 识别思路
通过图像识别技术直接识别点触验证码难度较大,尤其是复杂的文字和图像。识别难点包括文字的变形、模糊处理等,使得 OCR(光学字符识别)技术难以准确识别。因此,我们将借助第三方平台,如超级鹰,来实现验证码的自动识别。这些平台通过人工和机器结合的方式,提供高准确率的验证码识别服务。
5. 注册账号
首先,我们需要注册一个超级鹰账号并申请一个软件 ID。可以在超级鹰官网进行注册。注册完成后,前往开发者中心添加一个软件 ID,并充值一些题分。
6. 获取 API
超级鹰提供了 Java API,用于与其服务对接。以下是适用于 Java 的 API 代码:
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Chaojiying {
private String username;
private String password;
private String softId;
public Chaojiying(String username, String password, String softId) throws NoSuchAlgorithmException {
this.username = username;
this.password = md5(password);
this.softId = softId;
}
private String md5(String text) throws NoSuchAlgorithmException {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(text.getBytes());
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public Map<String, Object> postPic(byte[] img, int codeType) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://upload.chaojiying.net/Upload/Processing.php");
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addTextBody("user", username)
.addTextBody("pass2", password)
.addTextBody("softid", softId)
.addTextBody("codetype", String.valueOf(codeType))
.addBinaryBody("userfile", img, ContentType.DEFAULT_BINARY, "captcha.jpg")
.build();
httpPost.setEntity(reqEntity);
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
String responseString = EntityUtils.toString(resEntity);
httpClient.close();
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(responseString, HashMap.class);
}
public Map<String, Object> reportError(String imgId) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://upload.chaojiying.net/Upload/ReportError.php");
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addTextBody("user", username)
.addTextBody("pass2", password)
.addTextBody("softid", softId)
.addTextBody("id", imgId)
.build();
httpPost.setEntity(reqEntity);
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity resEntity = response.getEntity();
String responseString = EntityUtils.toString(resEntity);
httpClient.close();
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(responseString, HashMap.class);
}
}
7. 初始化
首先,我们初始化一些变量和对象,如 WebDriver 和 Chaojiying 对象:
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.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
public class CrackTouClick {
private static final String EMAIL = "your_email@example.com";
private static final String PASSWORD = "your_password";
private static final String CHAOJIYING_USERNAME = "your_username";
private static final String CHAOJIYING_PASSWORD = "your_password";
private static final String CHAOJIYING_SOFT_ID = "your_soft_id";
private static final int CHAOJIYING_KIND = 9102;
private WebDriver driver;
private WebDriverWait wait;
private Chaojiying chaojiying;
public CrackTouClick() throws NoSuchAlgorithmException {
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
this.driver = new ChromeDriver();
this.wait = new WebDriverWait(driver, 20);
this.chaojiying = new Chaojiying(CHAOJIYING_USERNAME, CHAOJIYING_PASSWORD, CHAOJIYING_SOFT_ID);
}
public void open() {
driver.get("http://admin.touclick.com/login.html");
WebElement email = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("email")));
WebElement password = wait.until(ExpectedConditions.presenceOfElementLocated(By.id("password")));
email.sendKeys(EMAIL);
password.sendKeys(PASSWORD);
}
public WebElement getTouClickButton() {
return wait.until(ExpectedConditions.elementToBeClickable(By.className("touclick-hod-wrap")));
}
public WebElement