selenium 获取浏览器的响应体

方案0 添加代理

基于代理工具(如 Fiddler 或 BrowserMob-Proxy)

通过代理工具拦截所有网络请求,获取响应体。适用于复杂场景(如需要修改请求 / 响应),但需额外启动代理服务。

实现步骤(以 BrowserMob-Proxy 为例):

  1. 安装 BrowserMob-Proxy

    • 下载地址:BrowserMob-Proxy

    • 解压后启动代理服务(默认端口 8080):

      browsermob-proxy.bat --port 8080
      
  2. 配置 Selenium 使用代理

    // 连接到代理服务
    var proxyServer = new OpenQA.Selenium.Proxy();
    proxyServer.HttpProxy = "localhost:8080"; // 代理服务地址
    options.Proxy = proxyServer;
    
    // 初始化 driver(你的现有代码,添加代理配置后)
    driver = new ChromeDriver(service, options);
    
    // 通过代理 API 获取所有请求响应(需引入 BrowserMob.Proxy 库)
    var client = new BrowserMob.Proxy.Client("localhost", 8080);
    client.NewHar("监控会话"); // 创建一个新的 HAR 日志
    
    // 访问页面后,获取 HAR 日志(包含所有请求响应)
    driver.Navigate().GoToUrl("https://目标网站.com");
    var har = client.GetHar();
    foreach (var entry in har.Log.Entries)
    {
        Console.WriteLine($"URL: {entry.Request.Url}");
        Console.WriteLine($"响应体: {entry.Response.Content.Text}\n");
    }
    
  3. 注意事项

    • 需安装 BrowserMob.Proxy NuGet 包:Install-Package BrowserMob.Proxy
    • 代理服务需与 Selenium 同时运行,且代理端口不能被占用。

方案一driver.getlog获取浏览器请求和响应

  // 1. 打开登录页面
            driver.Navigate().GoToUrl("http://127.0.0.1:9527/json/version");
            // 获取 Performance 日志
            var performanceLogs = driver.Manage().Logs.GetLog(LogType.Performance);

            foreach (var log in performanceLogs)
            {
                try
                {
                    // 解析日志的 JSON 内容
                    JObject logJson = JObject.Parse(log.Message);
                    JObject message = (JObject)logJson["message"]["message"];
                    string method = message["method"].ToString();
                    JObject param = (JObject)message["params"];

                    // 1. 筛选请求事件(Network.requestWillBeSent)
                    if (method == "Network.requestWillBeSent")
                    {
                        var request = param["request"];
                        string url = request["url"].ToString();
                        string method2 = request["method"].ToString();
                        // 筛选 XHR 请求(根据类型或 URL 关键字)
                        if (param["type"]?.ToString() == "XHR" || url.Contains("http"))
                        {
                            Console.WriteLine($"【请求】{method2} {url}");
                            Console.WriteLine($"请求头: {JsonConvert.SerializeObject(request["headers"])}");
                            Console.WriteLine($"请求体: {request["postData"]}\n");
                        }
                    }

                    // 2. 筛选响应事件(Network.responseReceived)
                    else if (method == "Network.responseReceived")
                    {
                        var response = param["response"];
                        string url = response["url"].ToString();
                        int status = (int)response["status"];
                        // 筛选 XHR 响应
                        if (param["type"]?.ToString() == "XHR" || url.Contains("http"))
                        {
                            Console.WriteLine($"【响应】{status} {url}");
                            Console.WriteLine($"响应头: {JsonConvert.SerializeObject(response["headers"])}");
                            // 响应体需要通过 CDP 单独获取(Performance 日志不包含响应体)
                            Console.WriteLine("响应体: [需通过 Network.getResponseBody 获取]\n");
                        }
                    }
                }
                catch (Exception ex)
                {
                    // 忽略解析错误的日志(部分日志可能非网络事件)
                    Console.WriteLine($"日志解析错误: {ex.Message}");
                }
            }

方案二 cdp

Chrome DevTools Protocol(CDP) 通过 Chrome DevTools Protocol 监听网络事件

   // 创建 DevTools 会话并启用网络监控
                        IDevTools devTools = driver as IDevTools; 
                        var devToolsSession = devTools.GetDevToolsSession();
                            
                        // 启用网络域
                        var network = devToolsSession.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V122.DevToolsSessionDomains>().Network;
                        network.Enable(new EnableCommandSettings());

                        // 监听请求事件
                        network.RequestWillBeSent += (sender, e) =>
                        {
                            if (e.Request.Url.Contains("qwen") ||
                                e.Request.Headers?.Any(h => h.Key == "X-Requested-With" && h.Value == "XMLHttpRequest") == true)
                             {
                                Console.WriteLine($"XHR 请求: {e.Request.Method} {e.Request.Url}");
                                //Console.WriteLine($"请求头: {System.Text.Json.JsonSerializer.Serialize(e.Request.Headers)}");
                                Console.WriteLine($"请求体: {e.Request.PostData}");
                            }
                        };

                        // 监听响应事件
                        network.ResponseReceived += (sender, e) =>
                        {
                            if (e.Response.Headers?.Any(h => h.Key == "X-Requested-With" && h.Value == "XMLHttpRequest") == true ||
                                e.Response.Url.Contains("user") || // 包含 api 的URL
                                e.Type == ResourceType.XHR)
                            {
                                Console.WriteLine($"XHR 响应: {e.Response.Status} {e.Response.StatusText}");
                                Console.WriteLine($"响应URL: {e.Response.Url}");
                                //Console.WriteLine($"响应头: {System.Text.Json.JsonSerializer.Serialize(e.Response.Headers)}");

                                // 获取响应体
                                Task.Run(async () =>
                                {
                                    try
                                    {
                                        var responseBody = await network.GetResponseBody(new GetResponseBodyCommandSettings
                                        {
                                            RequestId = e.RequestId
                                        });
                                        Console.WriteLine($"响应体: {responseBody.Body}");
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine($"获取响应体失败: {ex.Message}");
                                    }
                                });
                            }
                        }; 

方案三 Python库 selenium-wire