绕过验证码登录的方法
- 基于tess4j识别验证码
- 添加Cookie
- 利用SessionStorage或者LocalStorage绕过验证
1. 基于tess4j识别验证码
1)pom.xml添加tess4j
<dependency>
<groupId>net.sourceforge.tess4j</groupId>
<artifactId>tess4j</artifactId>
<version>4.5.2</version>
</dependency>
2)对于tess4j 4.5.2版本,windows平台下需要安装Microsoft Visual C++ 2015-2019 Redistributable,否则会报错
Exception in thread “main” java.lang.UnsatisfiedLinkError: 找不到指定模块
3)下载文字库放到指定文件夹tessdata下
4)具体实现代码:
public static void main(String[] args) throws IOException {
//初始化driver
ChromeOptions chromeOptions = new ChromeOptions();
driver = new ChromeDriver(chromeOptions);
driver.manage().window().setSize(new Dimension(1920,1080));
driver.get("http://localhost:port");
//定位验证码图片
WebElement ele = driver.findElement(By.id("s-canvas"));
File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
BufferedImage fullImg = ImageIO.read(screenshot); // 读取截图
//获取验证码图片x,y 坐标
org.openqa.selenium.Point point= ele.getLocation();
//剪裁图片
BufferedImage croppedImage = fullImg.getSubimage(point.x,point.y,ele.getSize().getWidth(),ele.getSize().getHeight());//进行裁剪
File imageFile = new File("Filepath");
ImageIO.write(croppedImage, "png", imageFile);
//识别
ITesseract instance = new Tesseract();
//指定文字库地址
instance.setDatapath(System.getProperty("user.dir")+"/src/main/resources/tessdata");
instance.setTessVariable("user_defined_dpi", "70");
String verifycode = null;
try {
verifycode = instance.doOCR(imageFile);
} catch (TesseractException e1) {
e1.printStackTrace();
}
verifycode = verifycode.replaceAll("[^a-z^A-Z^0-9]", "");//替换大小写及数字
System.out.println("Verify code is :" + verifycode);
}
实验结论:该种方法识别效果很差,基本识别不正确,只适用于验证码图片非常清晰的情况
若想提高识别效果,需要引入openCV等图像处理库,对图像进行二值化、膨胀、腐蚀等操作,时间成本过高,故放弃
2. 添加cookie
适用于是使用cookie登录的网站,具体代码如下:
public static void main(String[] args) throws IOException {
ChromeOptions chromeOptions = new ChromeOptions();
driver = new ChromeDriver(chromeOptions);
driver.manage().window().setSize(new Dimension(1920,1080));
driver.get("http://localhost:port");
Cookie c1 = new Cookie("key", "value");
driver.manage().addCookie(c1);
driver.navigate().refresh();
}
实验结果:我测试的目标网站未使用cookie,故放弃改方法
3. 利用Session Storage绕过验证码登录
不同系统不同,有的可能将登录信息存在Local Storage, 也有可能存在Session Storage里,具体可如下查看:F12查看Application -> Storage -> Local Storage/Session Storage
确认好登录信息是存在哪里后,执行js命令向Local Storage/Session Storage里设置登录信息,即可绕过验证码登录
我本次测试的目标系统是存在Session Storage中,如图:
具体代码如下:
// An highlighted block
public static void main(String[] args) throws IOException {
//初始化driver
ChromeOptions chromeOptions = new ChromeOptions();
driver = new ChromeDriver(chromeOptions);
driver.manage().window().setSize(new Dimension(1920,1080));
driver.get("http://localhost:port");
JavascriptExecutor driver_js= ((JavascriptExecutor) driver);
//设置user-info
String js = "sessionStorage.setItem('user-info','{\"token\":\"abc\"}');";
//执行js
driver_js.executeScript(js);
//刷新页面
driver.navigate().refresh();
}