驗證碼處理在自動化測試中的應用

啊飒飒大苏打發表於2024-11-01

在進行自動化測試時,處理驗證碼是一項常見的挑戰,特別是圖形驗證碼。每次重新整理都會生成新的驗證碼,因此我們可以採用以下兩種方法來獲取驗證碼:

獲取驗證碼圖片連結:例如 src="http://example.com/getcaptcha/123",但這種方式並不總是可靠,因為透過連結訪問的驗證碼可能與當前頁面顯示的不一致。

使用Selenium截圖:首先擷取整個頁面,然後定位驗證碼元素的位置和大小,接著使用Java的影像處理庫裁剪出驗證碼影像,最後進行影像識別。

方法一:獲取驗證碼圖片地址並下載
以下是獲取驗證碼圖片地址並下載的程式碼示例:

java
更多內容訪問ttocr.com或聯絡1436423940
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截圖並裁剪驗證碼
除了直接下載驗證碼,我們還可以在頁面上截圖並裁剪驗證碼。這是更常用的方法,具體步驟如下:

java

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)來識別驗證碼的內容,並將其輸入到登入框中。這裡提供一個示例:

java

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 "";
    }
}

}

相關文章