
本文旨在解决使用browsermob proxy与selenium进行网络请求头捕获时har文件为空的问题。我们将探讨传统代理方案的局限性,并详细介绍如何利用selenium 4内置的devtools api实现高效、稳定的网络流量(包括请求url、方法、头部信息)拦截与分析,提供完整的java示例代码和最佳实践,助力开发者进行前端调试和自动化测试。
在Web自动化测试、性能分析和前端调试中,捕获和分析浏览器发出的网络请求(包括请求头、响应头、请求体、响应体等)是至关重要的一环。传统上,开发者常借助第三方代理工具如Browsermob Proxy (BMP) 来实现这一目标。Browsermob Proxy作为一个基于HAR格式的HTTP代理,能够拦截浏览器与服务器之间的所有流量,并将其记录为HAR(HTTP Archive)文件,方便后续分析。
然而,在使用Browsermob Proxy结合Selenium进行自动化测试时,用户可能会遇到HAR文件记录为空的困境,即使正确配置了代理并尝试了多种捕获类型,也无法获取预期的网络日志。这通常是由于代理配置的复杂性、SSL证书处理、浏览器兼容性或时序问题导致的。例如,在无头模式下运行Chrome并配置BMP代理时,可能会因为证书信任问题或代理流量未正确路由而导致捕获失败。
以下是一个典型的Browsermob Proxy与Selenium结合的代码示例,它展示了尝试捕获HAR的常见模式,但可能面临HAR为空的问题:
import io.github.bonigarcia.wdm.WebDriverManager;
import net.lightbody.bmp.BrowserMobProxy;
import net.lightbody.bmp.BrowserMobProxyServer;
import net.lightbody.bmp.client.ClientUtil;
import net.lightbody.bmp.core.har.Har;
import net.lightbody.bmp.proxy.CaptureType;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.io.File;
import java.util.concurrent.TimeUnit;
public class BrowsermobProxyExample {
public static void main(String[] args) throws Exception {
WebDriver driver = null;
BrowserMobProxy proxy = new BrowserMobProxyServer();
proxy.setTrustAllServers(true); // 信任所有SSL证书
proxy.start(0); // 启动代理,端口随机
// 创建Selenium Proxy对象并关联Browsermob Proxy
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy);
String hostIp = "localhost";
seleniumProxy.setHttpProxy(hostIp + ":" + proxy.getPort());
seleniumProxy.setSslProxy(hostIp + ":" + proxy.getPort());
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless"); // 无头模式
options.addArguments("--ignore-certificate-errors"); // 忽略证书错误
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.PROXY, seleniumProxy);
capabilities.setCapability(CapabilityType.ACCEPT_INSECURE_CERTS, true);
options.merge(capabilities);
try {
driver = new ChromeDriver(options);
// 启用HAR捕获类型
proxy.enableHarCaptureTypes(CaptureType.REQUEST_HEADERS, CaptureType.RESPONSE_HEADERS,
CaptureType.REQUEST_CONTENT, CaptureType.RESPONSE_CONTENT);
proxy.newHar("example.com"); // 创建新的HAR文件
driver.get("https://www.example.com"); // 访问目标网站
TimeUnit.SECONDS.sleep(10); // 等待页面加载及网络请求完成
Har har = proxy.getHar(); // 获取HAR日志
har.writeTo(new File("test.har")); // 写入文件
System.out.println("HAR entries captured: " + har.getLog().getEntries().size());
} finally {
if (driver != null) {
driver.quit();
}
if (proxy != null) {
proxy.endHar();
proxy.stop();
}
}
}
}尽管上述代码逻辑看似完整,但在实际运行中,特别是在某些复杂的网络环境下或特定Selenium/BrowserMob Proxy版本组合下,test.har文件中的entries列表可能依然为空。这促使我们寻找更稳定、更集成的解决方案。
随着Selenium 4的发布,其引入了与浏览器DevTools(开发者工具)API的直接集成,为网络请求拦截提供了一个更为强大和稳定的原生方法。通过DevTools API,我们可以直接与浏览器内部通信,监听并获取网络事件,而无需依赖外部代理。这种方法避免了代理配置、SSL证书信任等复杂问题,使得网络流量捕获更加可靠。
以下是使用Selenium 4 DevTools API拦截网络请求头的详细步骤和示例代码:
2.2.1 准备工作
确保您的项目中引入了Selenium 4.6.0或更高版本的依赖。
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.7.0</version> <!-- 推荐使用最新稳定版本 -->
</dependency>2.2.2 示例代码
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v120.network.Network; // 根据Selenium版本调整vXXX
import org.openqa.selenium.devtools.v120.network.model.RequestWillBeSent; // 根据Selenium版本调整vXXX
import java.util.Optional;
import java.util.concurrent.TimeUnit;
public class DevToolsNetworkInterceptor {
public static void main(String[] args) throws InterruptedException {
// 1. 初始化ChromeDriver
// 确保ChromeDriver与您的Chrome浏览器版本兼容
// System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
// 或者使用WebDriverManager自动管理驱动
// WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
// options.addArguments("--headless"); // 如果需要无头模式,可以添加此参数
ChromeDriver driver = new ChromeDriver(options);
// 2. 获取DevTools实例并创建会话
DevTools devTools = driver.getDevTools();
devTools.createSession();
// 3. 启用Network域
// Optional.empty() 表示不设置额外的参数,如最大请求体大小、最大响应体大小等
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
// 4. 添加监听器,捕获请求发送事件
devTools.addListener(Network.requestWillBeSent(), request -> {
System.out.println("--------------------------------------------------");
System.out.println("Request URL: " + request.getRequest().getUrl());
System.out.println("Request Method: " + request.getRequest().getMethod());
System.out.println("Request Headers: " + request.getRequest().getHeaders().toJson());
System.out.println("--------------------------------------------------");
});
// (可选)添加监听器,捕获响应接收事件
devTools.addListener(Network.responseReceived(), response -> {
System.out.println("Response URL: " + response.getResponse().getUrl());
System.out.println("Response Status: " + response.getResponse().getStatus());
System.out.println("Response Headers: " + response.getResponse().getHeaders().toJson());
});
// 5. 导航到目标URL
driver.get("https://www.google.com");
// 6. 等待一段时间,确保网络请求有足够时间被捕获和处理
// 在实际应用中,应使用WebDriverWait等显式等待机制,而不是Thread.sleep
TimeUnit.SECONDS.sleep(10);
// 7. 关闭浏览器和DevTools会话
devTools.close();
driver.quit();
}
}代码解析:
除了requestWillBeSent,Network域还提供了许多其他有用的事件和命令,例如:
通过组合这些事件,您可以构建出更复杂的网络监控和控制逻辑。
Selenium 4提供的DevTools API为Java自动化测试带来了强大的网络请求拦截能力,有效解决了传统Browsermob Proxy方案中可能出现的HAR文件为空等问题。通过直接与浏览器DevTools协议交互,开发者可以更稳定、更细致地控制和监控网络流量,从而提升自动化测试的深度和效率。掌握这一技术,对于进行API测试、性能分析、安全审计以及复杂前端调试的工程师而言,无疑是一个重要的工具。
以上就是使用Selenium 4 DevTools API进行网络请求拦截与分析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号