You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Selenium Java捕获开发者工具中指定API的响应数据

使用Selenium Java获取指定API响应数据的问题及修正方案

我想用Selenium Java获取开发者工具中某一指定API预览面板里的数据,但尝试后没成功,以下是我的代码:

public class CapAPIResponse {

    EdgeDriver driver;
        
    @Test
    public void seleniumTest() {
        driver = new EdgeDriver();
        DevTools devTools = driver.getDevTools(); 
        devTools.createSession();
        devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
        devTools.addListener(Network.requestWillBeSent(), requestConsumer ->{
            Request request = requestConsumer.getRequest();
            System.out.println(request.getUrl());
        });
        
        final RequestId[] requestId = new RequestId[1];
        
        devTools.addListener(Network.responseReceived(), responseConsumer -> {
            Response response = responseConsumer.getResponse();
            requestId[0] = responseConsumer.getRequestId(); 
            if( response.getUrl().contains("ws_api.php?")) {
                System.out.println(response.getStatus() + " "+ response.getUrl());
                Assert.assertEquals(response.getStatus() , 200);
                String responseBody = devTools.send(Network.getResponseBody(requestId[0] )).getBody();
                System.err.println(responseBody);
            }   
            
        });
        driver.get("https://weatherstack.com/");
     
    }
}

问题分析

原代码存在几个核心问题导致获取不到响应数据:

  • responseReceived事件触发时,响应体可能还未完全加载完成,此时调用getResponseBody会返回空或抛出异常
  • 用数组存储requestId存在线程安全风险,DevTools监听器是异步执行的,可能出现ID覆盖的情况
  • 没有处理响应体为空的场景,容易出现空指针异常

修正后的代码

import org.junit.Assert;
import org.junit.Test;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.v125.network.Network;
import org.openqa.selenium.devtools.v125.network.model.RequestId;
import java.util.Optional;

public class CapAPIResponse {

    EdgeDriver driver;

    @Test
    public void seleniumTest() {
        driver = new EdgeDriver();
        DevTools devTools = driver.getDevTools();
        devTools.createSession();

        // 启用Network监控,设置最大请求缓存数,避免丢失请求
        devTools.send(Network.enable(Optional.of(1000000), Optional.empty(), Optional.empty()));

        // 监听请求加载完成事件,确保响应体已完全就绪
        devTools.addListener(Network.loadingFinished(), loadingFinished -> {
            RequestId currentRequestId = loadingFinished.getRequestId();
            
            // 获取请求对应的响应头,判断是否为目标API
            devTools.send(Network.getResponseHeaders(currentRequestId)).ifPresent(responseHeaders -> {
                String apiUrl = responseHeaders.getUrl();
                if (apiUrl.contains("ws_api.php?")) {
                    // 获取响应体,处理空值情况
                    devTools.send(Network.getResponseBody(currentRequestId)).ifPresent(responseBody -> {
                        System.out.println("目标API状态码:" + responseHeaders.getStatus());
                        System.out.println("目标API地址:" + apiUrl);
                        System.out.println("响应体内容:");
                        System.err.println(responseBody.getBody());
                        Assert.assertEquals(200, responseHeaders.getStatus());
                    });
                }
            });
        });

        driver.get("https://weatherstack.com/");
        
        // 等待页面加载完成并触发API请求,实际项目建议用显式等待替代Thread.sleep
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        driver.quit();
    }
}

关键修正说明

  • 改用loadingFinished事件:该事件在请求完全加载完成后触发,保证响应体已经可以被获取
  • 避免共享变量风险:直接在回调中使用当前请求的RequestId,不再用数组存储共享ID
  • 空值安全处理:使用Optional的ifPresent方法,避免因响应头或响应体为空导致的空指针异常
  • 添加等待逻辑:确保页面有足够时间加载并触发目标API请求,实际项目推荐用Selenium的显式等待(如等待页面某个元素加载完成)替代Thread.sleep
  • 关闭驱动资源:测试结束后调用driver.quit()释放浏览器资源

内容的提问来源于stack exchange,提问作者Delta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 22:46:30