Selenium BIDI:捕获Web应用特定请求且不篡改响应的方法
解决方案
一、不篡改响应使用NetworkInterceptor
你当前的问题核心是返回了空的HttpResponse(),导致Web应用无法获取正常响应,进而引发状态异常、自动登出。要实现仅读取请求信息而不修改响应,只需在拦截逻辑中转发原始请求到真实服务器,而非返回自定义空响应。
修改后的代码示例:
import org.openqa.selenium.devtools.NetworkInterceptor; import org.openqa.selenium.remote.http.HttpHandler; import org.openqa.selenium.remote.http.HttpRequest; import org.openqa.selenium.remote.http.HttpResponse; import static org.openqa.selenium.remote.http.Route.matching; // 初始化WebDriver和DevTools的代码保持不变 webDriver = new Augmenter().augment(webDriver); devTools = ((HasDevTools) webDriver).getDevTools(); devTools.createSession(); this.interceptor = new NetworkInterceptor( webDriver, matching(req -> req.getUri().contains(URL) && req.getMethod().equals(HttpMethod.POST)) .to(HttpHandler::createDefaultHandler()) // 转发请求到真实服务器 .andThen((req, handler) -> { // 读取并验证请求信息 System.out.println("捕获到目标请求:"); System.out.println("URI: " + req.getUri()); System.out.println("请求方法: " + req.getMethod()); // 如需验证请求体,可通过req.getContent()获取 // String requestBody = new String(req.getContent().orElse(new byte[0])); // 获取真实响应并返回,确保应用正常接收 HttpResponse realResponse = handler.execute(req); // 若需要,也可在此读取响应信息 return realResponse; }) );
二、其他替代方法
1. 封装DevTools Network监听(弱化版本依赖)
如果只是不想直接使用版本绑定的CDP API,可以通过抽象层或反射封装通用监听逻辑:
import org.openqa.selenium.devtools.DevTools; import org.openqa.selenium.devtools.network.Network; import java.util.Optional; // 初始化DevTools代码保持不变 devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty())); devTools.addListener(Network.requestWillBeSent(), requestEvent -> { String reqUrl = requestEvent.getRequest().getUrl(); String reqMethod = requestEvent.getRequest().getMethod(); if (reqUrl.contains(URL) && "POST".equals(reqMethod)) { // 验证请求信息 System.out.println("请求URL: " + reqUrl); System.out.println("请求Headers: " + requestEvent.getRequest().getHeaders()); } });
若担心CDP版本兼容,可通过反射动态加载对应版本的Network类,避免硬编码版本号。
2. 使用代理服务器(完全脱离CDP依赖)
通过BrowserMob Proxy这类代理工具拦截请求,无需依赖Chrome DevTools协议:
import net.lightbody.bmp.BrowserMobProxy; import net.lightbody.bmp.BrowserMobProxyServer; import net.lightbody.bmp.client.ClientUtil; import net.lightbody.bmp.core.har.HarEntry; import org.openqa.selenium.Proxy; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.WebDriver; import java.util.List; // 启动代理服务器 BrowserMobProxy proxy = new BrowserMobProxyServer(); proxy.start(0); Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy); // 配置浏览器使用代理 ChromeOptions options = new ChromeOptions(); options.setProxy(seleniumProxy); WebDriver webDriver = new ChromeDriver(options); // 开始捕获请求 proxy.newHar("app-requests"); // 执行Web应用操作... // 读取并验证捕获的请求 List<HarEntry> entries = proxy.getHar().getLog().getEntries(); for (HarEntry entry : entries) { String reqUrl = entry.getRequest().getUrl(); String reqMethod = entry.getRequest().getMethod(); if (reqUrl.contains(URL) && "POST".equals(reqMethod)) { System.out.println("请求URL: " + reqUrl); System.out.println("请求体: " + entry.getRequest().getPostData()); } }
内容的提问来源于stack exchange,提问作者deepakguna
相关产品推荐
相关产品推荐

