Java+Selenium 浏览器操作详解
目录
浏览器基础操作
1.1 启动和关闭浏览器
启动浏览器
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.edge.EdgeDriver;
public class BrowserBasics {
public static void main(String[] args) {
// 启动Chrome浏览器
System.setProperty("webdriver.chrome.driver", "path/to/chromedriver.exe");
WebDriver driver = new ChromeDriver();
// 启动Firefox浏览器
// System.setProperty("webdriver.gecko.driver", "path/to/geckodriver.exe");
// WebDriver driver = new FirefoxDriver();
// 启动Edge浏览器
// System.setProperty("webdriver.edge.driver", "path/to/msedgedriver.exe");
// WebDriver driver = new EdgeDriver();
}
}
关闭浏览器
// 关闭当前窗口
driver.close();
// 关闭所有窗口并退出浏览器进程
driver.quit();
新手提示:
close()只关闭当前窗口,如果只有一个窗口则关闭浏览器quit()关闭所有窗口并结束WebDriver会话,推荐使用
1.2 打开网页
// 打开指定URL
driver.get("https://www.baidu.com");
// 使用navigate方法打开(功能相同)
driver.navigate().to("https://www.baidu.com");
浏览器窗口管理
2.1 窗口大小操作
设置窗口大小
import org.openqa.selenium.Dimension;
// 设置窗口大小为1920x1080
Dimension size = new Dimension(1920, 1080);
driver.manage().window().setSize(size);
// 获取当前窗口大小
Dimension currentSize = driver.manage().window().getSize();
System.out.println("窗口宽度: " + currentSize.getWidth());
System.out.println("窗口高度: " + currentSize.getHeight());
窗口位置操作
import org.openqa.selenium.Point;
// 设置窗口位置
Point position = new Point(100, 50);
driver.manage().window().setPosition(position);
// 获取当前窗口位置
Point currentPosition = driver.manage().window().getPosition();
System.out.println("窗口X坐标: " + currentPosition.getX());
System.out.println("窗口Y坐标: " + currentPosition.getY());
窗口状态管理
// 最大化窗口
driver.manage().window().maximize();
// 最小化窗口(Selenium 4.0+)
driver.manage().window().minimize();
// 全屏显示
driver.manage().window().fullscreen();
2.2 多窗口操作
获取窗口句柄
// 获取当前窗口句柄
String currentWindow = driver.getWindowHandle();
System.out.println("当前窗口句柄: " + currentWindow);
// 获取所有窗口句柄
Set<String> allWindows = driver.getWindowHandles();
System.out.println("总窗口数: " + allWindows.size());
切换窗口
// 打开新窗口的链接
driver.findElement(By.linkText("新窗口链接")).click();
// 获取所有窗口句柄
Set<String> allWindows = driver.getWindowHandles();
// 切换到新窗口
for (String window : allWindows) {
if (!window.equals(currentWindow)) {
driver.switchTo().window(window);
break;
}
}
// 切换回原窗口
driver.switchTo().window(currentWindow);
实用的窗口切换方法
public class WindowHelper {
/**
* 切换到最新打开的窗口
*/
public static void switchToLatestWindow(WebDriver driver) {
Set<String> handles = driver.getWindowHandles();
String latestHandle = handles.toArray(new String[0])[handles.size() - 1];
driver.switchTo().window(latestHandle);
}
/**
* 根据窗口标题切换窗口
*/
public static boolean switchToWindowByTitle(WebDriver driver, String title) {
Set<String> handles = driver.getWindowHandles();
for (String handle : handles) {
driver.switchTo().window(handle);
if (driver.getTitle().contains(title)) {
return true;
}
}
return false;
}
}
浏览器导航操作
3.1 基本导航
// 前进
driver.navigate().forward();
// 后退
driver.navigate().back();
// 刷新页面
driver.navigate().refresh();
// 跳转到指定URL
driver.navigate().to("https://www.example.com");
3.2 导航历史管理
public class NavigationExample {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
// 访问多个页面
driver.get("https://www.baidu.com");
Thread.sleep(2000);
driver.get("https://www.google.com");
Thread.sleep(2000);
driver.get("https://www.bing.com");
Thread.sleep(2000);
// 后退到Google
driver.navigate().back();
System.out.println("当前页面: " + driver.getTitle());
// 再后退到百度
driver.navigate().back();
System.out.println("当前页面: " + driver.getTitle());
// 前进到Google
driver.navigate().forward();
System.out.println("当前页面: " + driver.getTitle());
driver.quit();
}
}
浏览器信息获取
4.1 页面信息获取
// 获取页面标题
String title = driver.getTitle();
System.out.println("页面标题: " + title);
// 获取当前URL
String currentUrl = driver.getCurrentUrl();
System.out.println("当前URL: " + currentUrl);
// 获取页面源码
String pageSource = driver.getPageSource();
System.out.println("页面源码长度: " + pageSource.length());
4.2 浏览器信息获取
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
// 获取浏览器信息
Capabilities caps = ((RemoteWebDriver) driver).getCapabilities();
System.out.println("浏览器名称: " + caps.getBrowserName());
System.out.println("浏览器版本: " + caps.getVersion());
System.out.println("平台: " + caps.getPlatform());
浏览器设置和配置
5.1 Chrome浏览器配置
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class ChromeConfiguration {
public static WebDriver createChromeDriver() {
ChromeOptions options = new ChromeOptions();
// 无头模式(后台运行,不显示浏览器界面)
options.addArguments("--headless");
// 禁用图片加载(提高速度)
options.addArguments("--blink-settings=imagesEnabled=false");
// 设置窗口大小
options.addArguments("--window-size=1920,1080");
// 禁用GPU加速
options.addArguments("--disable-gpu");
// 禁用沙盒模式
options.addArguments("--no-sandbox");
// 禁用开发者扩展
options.addArguments("--disable-extensions");
// 设置用户代理
options.addArguments("--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36");
// 忽略证书错误
options.addArguments("--ignore-certificate-errors");
return new ChromeDriver(options);
}
}
5.2 Firefox浏览器配置
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile;
public class FirefoxConfiguration {
public static WebDriver createFirefoxDriver() {
FirefoxOptions options = new FirefoxOptions();
FirefoxProfile profile = new FirefoxProfile();
// 禁用图片加载
profile.setPreference("permissions.default.image", 2);
// 禁用CSS
profile.setPreference("permissions.default.stylesheet", 2);
// 禁用JavaScript(谨慎使用)
// profile.setPreference("javascript.enabled", false);
// 设置下载目录
profile.setPreference("browser.download.dir", "C:\Downloads");
profile.setPreference("browser.download.folderList", 2);
// 无头模式
options.setHeadless(true);
options.setProfile(profile);
return new FirefoxDriver(options);
}
}
Cookie操作
6.1 基本Cookie操作
import org.openqa.selenium.Cookie;
public class CookieOperations {
public static void demonstrateCookies(WebDriver driver) {
// 访问网站
driver.get("https://www.baidu.com");
// 添加Cookie
Cookie cookie = new Cookie("testCookie", "testValue");
driver.manage().addCookie(cookie);
// 添加带有更多属性的Cookie
Cookie detailedCookie = new Cookie.Builder("userPreference", "darkMode")
.domain(".baidu.com")
.path("/")
.isSecure(false)
.isHttpOnly(false)
.build();
driver.manage().addCookie(detailedCookie);
// 获取所有Cookie
Set<Cookie> allCookies = driver.manage().getCookies();
System.out.println("总Cookie数量: " + allCookies.size());
for (Cookie c : allCookies) {
System.out.println("Cookie名称: " + c.getName() + ", 值: " + c.getValue());
}
// 获取特定Cookie
Cookie specificCookie = driver.manage().getCookieNamed("testCookie");
if (specificCookie != null) {
System.out.println("找到Cookie: " + specificCookie.getValue());
}
// 删除特定Cookie
driver.manage().deleteCookieNamed("testCookie");
// 删除所有Cookie
driver.manage().deleteAllCookies();
}
}
6.2 Cookie持久化
import java.io.*;
import java.util.Set;
import java.util.StringTokenizer;
public class CookiePersistence {
/**
* 保存Cookie到文件
*/
public static void saveCookiesToFile(WebDriver driver, String filePath) {
try {
FileWriter file = new FileWriter(filePath);
BufferedWriter Bwrite = new BufferedWriter(file);
Set<Cookie> cookies = driver.manage().getCookies();
for (Cookie cookie : cookies) {
Bwrite.write(cookie.getName() + ";" + cookie.getValue() + ";" +
cookie.getDomain() + ";" + cookie.getPath() + ";" +
cookie.getExpiry() + ";" + cookie.isSecure());
Bwrite.newLine();
}
Bwrite.close();
file.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 从文件加载Cookie
*/
public static void loadCookiesFromFile(WebDriver driver, String filePath) {
try {
File file = new File(filePath);
FileReader fileReader = new FileReader(file);
BufferedReader Buffreader = new BufferedReader(fileReader);
String strline;
while ((strline = Buffreader.readLine()) != null) {
StringTokenizer token = new StringTokenizer(strline, ";");
while (token.hasMoreTokens()) {
String name = token.nextToken();
String value = token.nextToken();
String domain = token.nextToken();
String path = token.nextToken();
Date expiry = null;
String val;
if (!(val = token.nextToken()).equals("null")) {
expiry = new Date(val);
}
Boolean isSecure = new Boolean(token.nextToken());
Cookie cookie = new Cookie(name, value, domain, path, expiry, isSecure);
driver.manage().addCookie(cookie);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
JavaScript执行
7.1 基本JavaScript执行
import org.openqa.selenium.JavascriptExecutor;
public class JavaScriptOperations {
public static void executeJavaScript(WebDriver driver) {
JavascriptExecutor js = (JavascriptExecutor) driver;
// 执行简单的JavaScript
js.executeScript("alert('Hello from Selenium!');");
// 滚动页面
js.executeScript("window.scrollTo(0, document.body.scrollHeight);");
// 滚动到指定位置
js.executeScript("window.scrollTo(0, 500);");
// 获取页面高度
Long pageHeight = (Long) js.executeScript("return document.body.scrollHeight;");
System.out.println("页面高度: " + pageHeight);
// 获取页面标题
String title = (String) js.executeScript("return document.title;");
System.out.println("页面标题: " + title);
// 修改页面元素
js.executeScript("document.getElementById('someId').style.backgroundColor = 'red';");
// 点击元素(当普通click()不工作时)
WebElement element = driver.findElement(By.id("someButton"));
js.executeScript("arguments[0].click();", element);
}
}
7.2 高级JavaScript操作
public class AdvancedJavaScript {
/**
* 高亮显示元素
*/
public static void highlightElement(WebDriver driver, WebElement element) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].style.border='3px solid red'", element);
}
/**
* 移除元素高亮
*/
public static void removeHighlight(WebDriver driver, WebElement element) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].style.border=''", element);
}
/**
* 平滑滚动到元素
*/
public static void smoothScrollToElement(WebDriver driver, WebElement element) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView({behavior: 'smooth'});", element);
}
/**
* 获取元素的所有属性
*/
public static void getElementAttributes(WebDriver driver, WebElement element) {
JavascriptExecutor js = (JavascriptExecutor) driver;
String script = "var items = {}; " +
"for (index = 0; index < arguments[0].attributes.length; ++index) { " +
"items[arguments[0].attributes[index].name] = arguments[0].attributes[index].value }; " +
"return items;";
Map<String, String> attributes = (Map<String, String>) js.executeScript(script, element);
for (Map.Entry<String, String> entry : attributes.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
}
截图操作
8.1 基本截图
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ScreenshotOperations {
/**
* 截取整个页面
*/
public static void takeScreenshot(WebDriver driver, String fileName) {
try {
TakesScreenshot screenshot = (TakesScreenshot) driver;
File sourceFile = screenshot.getScreenshotAs(OutputType.FILE);
File destFile = new File(fileName);
FileUtils.copyFile(sourceFile, destFile);
System.out.println("截图已保存: " + fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 带时间戳的截图
*/
public static void takeTimestampedScreenshot(WebDriver driver, String directory) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
String timestamp = dateFormat.format(new Date());
String fileName = directory + "/screenshot_" + timestamp + ".png";
takeScreenshot(driver, fileName);
}
/**
* 截取特定元素
*/
public static void takeElementScreenshot(WebElement element, String fileName) {
try {
File sourceFile = element.getScreenshotAs(OutputType.FILE);
File destFile = new File(fileName);
FileUtils.copyFile(sourceFile, destFile);
System.out.println("元素截图已保存: " + fileName);
} catch (IOException e) {
e.printStackTrace();
}
}
}
8.2 截图工具类
public class ScreenshotUtils {
private static final String SCREENSHOT_DIR = "screenshots/";
static {
// 创建截图目录
new File(SCREENSHOT_DIR).mkdirs();
}
/**
* 失败时自动截图
*/
public static void captureFailureScreenshot(WebDriver driver, String testName) {
String fileName = SCREENSHOT_DIR + "FAILED_" + testName + "_" +
System.currentTimeMillis() + ".png";
takeScreenshot(driver, fileName);
}
/**
* 比较截图(需要额外的图像比较库)
*/
public static boolean compareScreenshots(String expectedImage, String actualImage) {
// 这里需要使用图像比较库,如AShot或ImageIO
// 简化示例
return true;
}
}
文件上传下载
9.1 文件上传
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
public class FileOperations {
/**
* 简单文件上传
*/
public static void uploadFile(WebDriver driver, String filePath) {
// 找到文件上传元素(input type="file")
WebElement fileInput = driver.findElement(By.xpath("//input[@type='file']"));
// 直接发送文件路径
fileInput.sendKeys(filePath);
}
/**
* 处理多文件上传
*/
public static void uploadMultipleFiles(WebDriver driver, String... filePaths) {
WebElement fileInput = driver.findElement(By.xpath("//input[@type='file']"));
// 多个文件路径用换行符分隔
String allFiles = String.join("n", filePaths);
fileInput.sendKeys(allFiles);
}
/**
* 使用Robot类处理复杂的文件选择对话框
*/
public static void uploadFileWithRobot(String filePath) {
try {
// 将文件路径复制到剪贴板
StringSelection stringSelection = new StringSelection(filePath);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(stringSelection, null);
Robot robot = new Robot();
// 粘贴文件路径
robot.keyPress(KeyEvent.VK_CONTROL);
robot.keyPress(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_V);
robot.keyRelease(KeyEvent.VK_CONTROL);
Thread.sleep(1000);
// 按回车确认
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
} catch (Exception e) {
e.printStackTrace();
}
}
}
9.2 文件下载配置
import org.openqa.selenium.chrome.ChromeOptions;
import java.util.HashMap;
import java.util.Map;
public class DownloadConfiguration {
/**
* 配置Chrome下载设置
*/
public static WebDriver createDownloadConfiguredDriver(String downloadPath) {
ChromeOptions options = new ChromeOptions();
Map<String, Object> prefs = new HashMap<>();
prefs.put("profile.default_content_settings.popups", 0);
prefs.put("download.default_directory", downloadPath);
prefs.put("download.prompt_for_download", false);
prefs.put("download.directory_upgrade", true);
prefs.put("safebrowsing.enabled", true);
options.setExperimentalOption("prefs", prefs);
return new ChromeDriver(options);
}
/**
* 等待文件下载完成
*/
public static boolean waitForDownload(String downloadPath, String fileName, int timeoutSeconds) {
File file = new File(downloadPath + "/" + fileName);
int waited = 0;
while (waited < timeoutSeconds) {
if (file.exists() && !isFileBeingDownloaded(downloadPath, fileName)) {
return true;
}
try {
Thread.sleep(1000);
waited++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return false;
}
private static boolean isFileBeingDownloaded(String downloadPath, String fileName) {
// 检查是否存在临时下载文件(.crdownload, .tmp等)
File tempFile = new File(downloadPath + "/" + fileName + ".crdownload");
return tempFile.exists();
}
}
实际应用示例
10.1 完整的浏览器操作示例
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.time.Duration;
public class ComprehensiveBrowserExample {
private WebDriver driver;
private WebDriverWait wait;
public void setUp() {
// 配置Chrome选项
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
options.addArguments("--disable-notifications");
driver = new ChromeDriver(options);
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
// 设置隐式等待
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}
public void demonstrateBrowserOperations() {
try {
// 1. 打开网页
driver.get("https://www.baidu.com");
System.out.println("当前页面标题: " + driver.getTitle());
// 2. 窗口操作
driver.manage().window().maximize();
System.out.println("窗口已最大化");
// 3. 获取页面信息
String currentUrl = driver.getCurrentUrl();
System.out.println("当前URL: " + currentUrl);
// 4. JavaScript操作
JavascriptExecutor js = (JavascriptExecutor) driver;
Long pageHeight = (Long) js.executeScript("return document.body.scrollHeight");
System.out.println("页面高度: " + pageHeight + "px");
// 5. 滚动操作
js.executeScript("window.scrollTo(0, document.body.scrollHeight/2)");
Thread.sleep(2000);
// 6. 截图
ScreenshotOperations.takeTimestampedScreenshot(driver, "screenshots");
// 7. Cookie操作
driver.manage().addCookie(new Cookie("testCookie", "seleniumTest"));
System.out.println("Cookie已添加");
// 8. 导航操作
driver.navigate().to("https://www.google.com");
Thread.sleep(2000);
driver.navigate().back();
System.out.println("已返回上一页: " + driver.getTitle());
// 9. 多窗口操作演示
String originalWindow = driver.getWindowHandle();
// 打开新标签页
js.executeScript("window.open('https://www.bing.com', '_blank');");
// 切换到新窗口
for (String windowHandle : driver.getWindowHandles()) {
if (!windowHandle.equals(originalWindow)) {
driver.switchTo().window(windowHandle);
break;
}
}
System.out.println("新窗口标题: " + driver.getTitle());
// 关闭新窗口并切换回原窗口
driver.close();
driver.switchTo().window(originalWindow);
} catch (Exception e) {
e.printStackTrace();
// 失败时截图
ScreenshotUtils.captureFailureScreenshot(driver, "browser_operations_failed");
}
}
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
public static void main(String[] args) {
ComprehensiveBrowserExample example = new ComprehensiveBrowserExample();
example.setUp();
example.demonstrateBrowserOperations();
example.tearDown();
}
}
10.2 浏览器工具类
public class BrowserUtils {
/**
* 等待页面完全加载
*/
public static void waitForPageLoad(WebDriver driver) {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(webDriver -> ((JavascriptExecutor) webDriver)
.executeScript("return document.readyState").equals("complete"));
}
/**
* 检查元素是否在视口中
*/
public static boolean isElementInViewport(WebDriver driver, WebElement element) {
JavascriptExecutor js = (JavascriptExecutor) driver;
return (Boolean) js.executeScript(
"var rect = arguments[0].getBoundingClientRect();" +
"return (rect.top >= 0 && rect.left >= 0 && " +
"rect.bottom <= window.innerHeight && rect.right <= window.innerWidth);",
element);
}
/**
* 获取浏览器控制台日志
*/
public static void printConsoleLogs(WebDriver driver) {
LogEntries logs = driver.manage().logs().get(LogType.BROWSER);
for (LogEntry entry : logs) {
System.out.println(entry.getLevel() + " " + entry.getMessage());
}
}
/**
* 清除浏览器缓存
*/
public static void clearBrowserCache(WebDriver driver) {
driver.manage().deleteAllCookies();
// 清除localStorage和sessionStorage
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("window.localStorage.clear();");
js.executeScript("window.sessionStorage.clear();");
}
}
最佳实践和注意事项
新手常见问题及解决方案
-
浏览器驱动问题
// 使用WebDriverManager自动管理驱动 // 添加依赖: io.github.bonigarcia:webdrivermanager WebDriverManager.chromedriver().setup(); WebDriver driver = new ChromeDriver(); -
等待时间设置
// 推荐使用显式等待而不是Thread.sleep() WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.titleContains("期望的标题")); -
异常处理
try { // 浏览器操作 driver.get("https://example.com"); } catch (TimeoutException e) { System.out.println("页面加载超时"); } catch (NoSuchWindowException e) { System.out.println("窗口不存在"); } finally { // 确保浏览器关闭 if (driver != null) { driver.quit(); } } -
资源清理
// 使用try-with-resources(需要实现AutoCloseable) public class WebDriverWrapper implements AutoCloseable { private WebDriver driver; public WebDriverWrapper() { this.driver = new ChromeDriver(); } @Override public void close() { if (driver != null) { driver.quit(); } } }
性能优化建议
-
禁用不必要的功能
ChromeOptions options = new ChromeOptions(); options.addArguments("--disable-images"); options.addArguments("--disable-javascript"); // 谨慎使用 options.addArguments("--disable-css"); -
使用无头模式
options.addArguments("--headless"); -
合理设置超时时间
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30)); driver.manage().timeouts().scriptTimeout(Duration.ofSeconds(30));
总结
本教程涵盖了Java+Selenium中的主要浏览器操作:
- 基础操作: 启动、关闭、导航
- 窗口管理: 大小、位置、多窗口切换
- 信息获取: 标题、URL、页面源码
- 高级功能: JavaScript执行、截图、文件操作
- 配置优化: 浏览器选项、性能调优
- 实用工具: Cookie管理、等待机制
新手学习建议:
- 从基础操作开始,逐步掌握高级功能
- 多练习多窗口操作和JavaScript执行
- 重视异常处理和资源清理
- 学会使用等待机制而不是固定延时
- 实际项目中要考虑性能优化
通过掌握这些浏览器操作,您就能够构建稳定可靠的自动化测试脚本了!