WebDriver 的 get() 方法族是瀏覽器自動化的入口與感知基礎。本文系統梳理 get(String url) 導航、getCurrentUrl()、getPageSource()、getTitle()、getWindowHandle()、getWindowHandles() 六大核心方法,附帶實戰代碼、常見坑點與最佳實踐。
| 方法 | 返回類型 | 用途 | 典型場景 |
|---|---|---|---|
get(String url) | void | 導航到指定 URL,阻塞直到頁面加載完成 (onload) | 打開首頁、跳轉業務頁 |
getCurrentUrl() | String | 獲取當前瀏覽器地址欄 URL | 斷言重定向、驗證登錄後跳轉 |
getPageSource() | String | 獲取當前頁面 HTML 源碼 (DOM 序列化後) | 正則提取數據、調試頁面結構、斷言關鍵字存在 |
getTitle() | String | 獲取頁面 <title> 內容 | 頁面加載驗證、多標籤頁切換確認 |
getWindowHandle() | String | 獲取當前窗口唯一句柄 (UUID) | 主窗口句柄保存,彈窗切換後返回 |
getWindowHandles() | Set<String> | 獲取所有打開窗口句柄集合 | 遍歷切換多標籤/彈窗 |
import org.junit.jupiter.api.*;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import io.github.bonigarcia.wdm.WebDriverManager;
import java.util.Set;
class WebDriverGetApiTest {
private WebDriver driver;
@BeforeEach
void setUp() {
WebDriverManager.chromedriver().setup();
driver = new ChromeDriver();
driver.manage().window().maximize();
}
@Test
void getApiDemo() {
// 1. 導航
driver.get("https://www.baidu.com");
// 2. 獲取基本信息
String url = driver.getCurrentUrl();
String title = driver.getTitle();
String source = driver.getPageSource();
String mainHandle = driver.getWindowHandle();
System.out.println("URL: " + url);
System.out.println("Title: " + title);
System.out.println("Source length: " + source.length());
System.out.println("Main handle: " + mainHandle);
// 斷言基本信息
Assertions.assertTrue(url.contains("baidu.com"));
Assertions.assertEquals("百度一下,你就知道", title);
Assertions.assertTrue(source.contains("wd")); // 搜索框 name
// 3. 多窗口處理示例:點擊「設置」鏈接通常新開標籤
// 假設有一個 target="_blank" 鏈接
// driver.findElement(By.linkText("設置")).click();
// 等待新窗口打開
// new WebDriverWait(driver, Duration.ofSeconds(5))
// .until(d -> d.getWindowHandles().size() > 1);
//
// Set handles = driver.getWindowHandles();
// for (String handle : handles) {
// if (!handle.equals(mainHandle)) {
// driver.switchTo().window(handle);
// System.out.println("Switched to: " + driver.getTitle());
// driver.close(); // 關閉新標籤
// break;
// }
// }
// driver.switchTo().window(mainHandle); // 切回主窗口
}
@AfterEach
void tearDown() {
if (driver != null) driver.quit();
}
}
| 坑點 | 現象 | 根因 | 解決方案 |
|---|---|---|---|
| get() 不阻塞 JS 渲染 | 頁面骨架載入完成返回,但 AJAX 數據未渲染 | WebDriver 僅等待 document.readyState === "complete" | 顯式等待關鍵元素可見/文本出現,不要信賴 get() 返回即代表業務就緒 |
| getPageSource() ≠ 原始響應 | 源碼中無原始 JS 模板、Vue/React 虛擬 DOM | 返回的是瀏覽器渲染後的 DOM 序列化 HTML | 需原始響應請用瀏覽器 DevTools Network 或代理 (BrowserMob Proxy) 捕獲 |
| getTitle() 為空 | 單頁應用 (SPA) 動態設置 title,獲取時機過早 | title 由 JS 異步修改 | 顯式等待 ExpectedConditions.titleContains("關鍵詞") |
| 窗口句柄不穩定 | 每次啟動句柄不同,跨會話無效 | 句柄為瀏覽器進程生成的臨時 UUID | 僅在當前會話內使用,持久化無意義 |
| 多窗口切換丟失焦點 | switchTo().window() 後元素不可交互 | 新窗口尚未激活/載入完成 | 切換後顯式等待目標窗口關鍵元素 |
driver.get("https://example.com/login");
driver.findElement(By.id("user")).sendKeys("admin");
driver.findElement(By.id("pwd")).sendKeys("123456");
driver.findElement(By.id("btn")).click();
// 等待重定向完成
new WebDriverWait(driver, Duration.ofSeconds(10))
.until(ExpectedConditions.urlContains("/dashboard"));
Assertions.assertTrue(driver.getCurrentUrl().endsWith("/dashboard"));
// 當元素定位器不穩定時,可退而求其次斷言源碼包含業務關鍵字
String source = driver.getPageSource();
Assertions.assertTrue(source.contains("訂單號: 20240101001"));
Assertions.assertTrue(source.contains("狀態: 已支付"));
String main = driver.getWindowHandle();
// 操作觸發新標籤 (如點擊 target="_blank" 鏈接、window.open)
driver.findElement(By.cssSelector("a[target='_blank']")).click();
// 等待並切換到新標籤
String newHandle = new WebDriverWait(driver, Duration.ofSeconds(10))
.until(d -> {
Set handles = d.getWindowHandles();
handles.remove(main);
return handles.isEmpty() ? null : handles.iterator().next();
});
driver.switchTo().window(newHandle);
// 業務操作...
driver.close(); // 關閉新標籤
driver.switchTo().window(main); // 回主流程
get() 系列 API 是 WebDriver 感知瀏覽器狀態的「五官」。掌握其 阻塞行為邊界、返回值語義、多窗口協作模式,配合 顯式等待 而非盲目信任同步返回,是編寫穩定自動化腳本的基石。記住:get() 返回 ≠ 業務就緒,顯式等待才是硬道理。