在进行自动化测试时,处理验证码是一项常见的挑战,特别是图形验证码。每次刷新都会生成新的验证码,因此我们可以采用以下两种方法来获取验证码:
获取验证码图片链接:例如 src="http://example.com/getcaptcha/123",但这种方式并不总是可靠,因为通过链接访问的验证码可能与当前页面显示的不一致。
使用Selenium截屏:首先截取整个页面,然后定位验证码元素的位置和大小,接着使用Java的图像处理库裁剪出验证码图像,最后进行图像识别。
方法一:获取验证码图片地址并下载
以下是获取验证码图片地址并下载的代码示例:
import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.net.URL;import java.util.Random;public class CaptchaDownloader {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");WebDriver driver = new ChromeDriver();driver.get("http://example.com/login");String captchaSrc = driver.findElement(By.id("captchaImage")).getAttribute("src");String imgUrl = captchaSrc + ".png"; // 拼接下载地址String fileName = String.valueOf(new Random().nextInt(100000)); // 生成随机文件名String filePath = "img/login/";saveImage(imgUrl, fileName, filePath); // 下载图片driver.quit();}private static void saveImage(String imgUrl, String fileName, String filePath) {try {URL url = new URL(imgUrl);InputStream in = url.openStream();FileOutputStream fos = new FileOutputStream(new File(filePath + fileName + ".png"));byte[] buffer = new byte[2048];int bytesRead;while ((bytesRead = in.read(buffer)) != -1) {fos.write(buffer, 0, bytesRead);}in.close();fos.close();System.out.println("图片保存成功");} catch (Exception e) {System.err.println("保存图片时发生错误: " + e.getMessage());}}}
方法二:使用Selenium截屏并裁剪验证码
除了直接下载验证码,我们还可以在页面上截屏并裁剪验证码。这是更常用的方法,具体步骤如下:
import org.openqa.selenium.OutputType;import org.openqa.selenium.TakesScreenshot;import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.By;import javax.imageio.ImageIO;import java.awt.image.BufferedImage;import java.io.File;import java.util.Random;public class CaptchaCutter {public static void main(String[] args) throws Exception {System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");WebDriver driver = new ChromeDriver();driver.get("http://example.com/login");// 截取整个页面File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);BufferedImage fullImg = ImageIO.read(screenshot);// 定位验证码元素WebElement captchaElement = driver.findElement(By.id("captchaImage"));int x = captchaElement.getLocation().getX();int y = captchaElement.getLocation().getY();int width = captchaElement.getSize().getWidth();int height = captchaElement.getSize().getHeight();// 裁剪验证码BufferedImage captchaImg = fullImg.getSubimage(x, y, width, height);String captchaFileName = "img/login/" + new Random().nextInt(100000) + "_captcha.png";ImageIO.write(captchaImg, "png", new File(captchaFileName));System.out.println("验证码裁剪并保存成功");driver.quit();}}
输入验证码并登录
接下来,我们可以使用图像识别库(例如 Tesseract)来识别验证码的内容,并将其输入到登录框中。这里提供一个示例:
import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.chrome.ChromeDriver;import java.io.File;import java.io.IOException;import net.sourceforge.tess4j.Tesseract;import net.sourceforge.tess4j.TesseractException;public class LoginWithCaptcha {public static void main(String[] args) {System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");WebDriver driver = new ChromeDriver();driver.get("http://example.com/login");// 输入用户名和密码driver.findElement(By.id("username")).sendKeys("your_username");driver.findElement(By.id("password")).sendKeys("your_password");// 识别验证码并输入String captchaFilePath = "img/login/your_captcha_file.png"; // 替换为实际文件路径String captchaText = recognizeCaptcha(captchaFilePath);driver.findElement(By.id("captchaInput")).sendKeys(captchaText);// 提交登录driver.findElement(By.id("loginButton")).click();// 检查登录状态if (driver.getPageSource().contains("欢迎")) {System.out.println("登录成功!");} else {System.out.println("登录失败,验证码可能输入错误。");}driver.quit();}private static String recognizeCaptcha(String filePath) {Tesseract tesseract = new Tesseract();tesseract.setDatapath("path/to/tessdata");try {return tesseract.doOCR(new File(filePath));} catch (TesseractException e) {System.err.println("识别验证码时发生错误: " + e.getMessage());return "";}}}
感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!有需要的小伙伴可以点击下方小卡片领取