自动化识别验证码 UI方式+接口方式
欢迎大家加群,共同讨论测试自动化,qq群:436370465
登录时经常要识别验证码
下面提供2种方式
1.UI方式
通过截图方式会去到验证码图片,借助打码平台识别验证码
首先截取验证码图片
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.*;
import org.apache.commons.io.FileUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
@Slf4j
public class Base {
/**
* UI方式获取验证码截图
* 验证码截图
*
* @param driver
* @param by
* @return
* @throws IOException
*/
public String verificationCodeScreenshot(WebDriver driver, By by) throws IOException {
String screenShotDirPath = System.getProperty("user.dir") + File.separator + "target" + File.separator + "test-output" + File.separator + "png" + File.separator;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HHmmssSSS");
String time = simpleDateFormat.format(new Date());
try {
log.info("准备截取图片验证码图片到本地");
WebElement element = driver.findElement(by);
// 获取验证码x,y轴坐标
Point location = element.getLocation();
// 获取验证码的长宽
int x = location.getX();
int y = location.getY();
int width = element.getSize().getWidth();
int height = element.getSize().getHeight();
//截屏
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshot);
//裁剪出验证码的截图
BufferedImage eleScreenshot = fullImg.getSubimage(location.getX(), location.getY(), width, height);
ImageIO.write(eleScreenshot, "png", screenshot);
//储存到指定位置
File screenshotLocation = new File(screenShotDirPath + time + "verify.png");
FileUtils.copyFile(screenshot, screenshotLocation);
log.info("成功保存验证码图片");
} catch (WebDriverException | IOException e) {
e.printStackTrace();
}
return screenShotDirPath + time + "verify.png";
}
}
然后将图片传给打码平台(我这边用的图鉴 ttshitu),获取验证码结果
/**
* 通过打码平台(图鉴)查找验证码
*
* @param filePath
* @return
* @throws IOException
*/
public String getVerificationCodeByttshitu(String filePath) throws IOException {
String ttshituHost = PropertyReader.getValue("ttshitu.host");
//用户名与密码我是写在了配置文件,从配置文件读取
String ttshituUsername = PropertyReader.getValue("ttshitu.username");
String ttshituPassword = PropertyReader.getValue("ttshitu.password");
String typeid = "3";
String remark = "输出计算结果";
InputStream inputStream = null;
File needRecoImage = new File(filePath);
inputStream = new FileInputStream(needRecoImage);
Map<String, String> data = new HashMap<>(20);
data.put("username", ttshituUsername);
data.put("password", ttshituPassword);
data.put("typeid", typeid);
data.put("remark", remark);
String resultString = "";
for (int i = 0; i < 5; i++) {
try {
log.info("图鉴地址是:" + ttshituHost);
resultString = Jsoup.connect(ttshituHost)
.data(data).data("image", "test.jpg", inputStream)
.ignoreContentType(true)
.post().text();
break;
} catch (Exception e) {
log.info("链接图鉴失败,准备尝试");
try {
Thread.sleep(3000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
}
}
JSONObject jsonObject = JSONObject.parseObject(resultString);
String result = "";
if (jsonObject.getBoolean("success")) {
result = jsonObject.getJSONObject("data").getString("result");
log.info("识别成功结果为:" + result);
} else {
log.info("识别失败原因为:" + jsonObject.getString("message"));
}
return result;
}

2.通过接口方式获取到验证码的密文报文,借助打码平台识别验证码
首先观察接口 拿到密文的图片压缩信息(与加密方式有关,我这边试base64)

/**
* 接口方式取验证码信息(base64加密的一串密文),传给打码平台返回验证码
* @return
*/
@SneakyThrows
public String getVerificationCodeByAPi(){
//能返回验证码信息的接口
JsonObject imageObj=userActive(manager);
//取出返回的验证码密文信息(我这边是base64加密的一串密文)
String image=imageObj.get("image").getAsString();
//调用打码平台识别验证码(图鉴)
String verifyCode = getVerificationCodeBybase64(image);
log.info("图片验证码是:"+verifyCode);
return verifyCode;
}
/**
* 通过imagebase64的方式获得图片验证码
*
* @param imagebase64
* @return
* @throws IOException
*/
public String getVerificationCodeBybase64(String imagebase64) throws IOException {
String ttshituHost = PropertyReader.getValue(ttHost);
String ttshituUsername = PropertyReader.getValue(ttUsername);
String ttshituPassword = PropertyReader.getValue(ttPassword);
String typeid = "3";
String remark = "输出计算结果";
InputStream inputStream = null;
Map<String, String> data = new HashMap<>(20);
data.put("username", ttshituUsername);
data.put("password", ttshituPassword);
data.put("typeid", "3");
data.put("remark", remark);
data.put("image", imagebase64);
String result = "";
String resultString = "";
for (int i = 0; i < 3; i++) {
try {
log.info("图鉴地址是:" + ttshituHost);
resultString = Jsoup.connect(ttshituHost)
.requestBody(JSON.toJSONString(data))
.header("Content-Type", "application/json")
.ignoreContentType(true).timeout(120000).post().text();
JSONObject jsonObject = JSONObject.parseObject(resultString);
if (jsonObject.getBoolean("success")) {
result = jsonObject.getJSONObject("data").getString("result");
System.out.println("识别成功结果为:" + result);
break;
} else {
System.out.println("识别失败原因为:" + jsonObject.getString("message"));
}
} catch (Exception e) {
log.info("链接图鉴失败,准备尝试");
try {
Thread.sleep(3000);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
}
}
return result;
}

浙公网安备 33010602011771号