.NET环境下如何实现Selenium ChromeDriver脚本日志的事件式获取
C# Selenium ChromeDriver 事件驱动获取浏览器控制台日志实现方案
Selenium 原生没有提供直接的浏览器日志回调事件接口,可通过以下两种方案实现新日志产生时自动触发事件的效果。
方案1:增量轮询封装实现(兼容所有Selenium版本)
通过低频次后台轮询+时间戳增量过滤的方式实现事件驱动效果,轮询开销极低,对整体性能无感知。
1.1 自定义日志事件参数
public class BrowserLogEventArgs : EventArgs { public LogEntry NewLogEntry { get; } public BrowserLogEventArgs(LogEntry logEntry) { NewLogEntry = logEntry; } }
1.2 封装事件驱动ChromeDriver类
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; public class EventDrivenChromeDriver : ChromeDriver { // 对外暴露的新日志触发事件 public event EventHandler<BrowserLogEventArgs> OnNewBrowserLog; private readonly CancellationTokenSource _listenCts = new(); private DateTime _lastLogTimestamp = DateTime.MinValue; private readonly int _pollIntervalMs; public EventDrivenChromeDriver(ChromeOptions options, int pollIntervalMs = 100) : base(options) { _pollIntervalMs = pollIntervalMs; // 启动后台日志监听任务 _ = StartLogListenTaskAsync(); } private async Task StartLogListenTaskAsync() { while (!_listenCts.IsCancellationRequested) { try { var allLogs = Manage().Logs.GetLog(LogType.Browser); if (allLogs.Count > 0) { // 筛选出时间晚于上次记录的新增日志 var newLogs = allLogs.Where(log => log.Timestamp > _lastLogTimestamp).ToList(); if (newLogs.Any()) { _lastLogTimestamp = newLogs.Max(log => log.Timestamp); // 逐个触发新日志事件 foreach (var log in newLogs) { OnNewBrowserLog?.Invoke(this, new BrowserLogEventArgs(log)); } } } await Task.Delay(_pollIntervalMs, _listenCts.Token); } catch (OperationCanceledException) { break; } catch { // 异常容错,避免监听任务崩溃,可按需添加异常日志逻辑 await Task.Delay(_pollIntervalMs, _listenCts.Token); } } } // 释放资源时自动终止监听任务 public override void Dispose() { _listenCts.Cancel(); _listenCts.Dispose(); base.Dispose(); } }
1.3 使用示例
// 配置Chrome选项,开启浏览器日志采集 var chromeOptions = new ChromeOptions(); chromeOptions.SetLoggingPreference(LogType.Browser, LogLevel.All); // 初始化事件驱动ChromeDriver,可自定义轮询间隔 using var driver = new EventDrivenChromeDriver(chromeOptions, pollIntervalMs: 50); // 绑定新日志回调 driver.OnNewBrowserLog += (sender, args) => { var log = args.NewLogEntry; Console.WriteLine($"[{log.Level}] [{log.Timestamp:HH:mm:ss.fff}] {log.Message}"); }; // 执行业务逻辑 driver.Navigate().GoToUrl("你的目标网站地址");
方案2:基于Chrome DevTools Protocol(CDP)的纯事件驱动实现(无轮询,性能最优)
直接调用Chrome底层的日志订阅接口,完全没有轮询开销,是真正的原生事件驱动方案。
注意:代码中的V120需要替换为你本地使用的Chrome浏览器对应的大版本号,DevTools包版本需要和Chrome版本匹配
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.DevTools; using OpenQA.Selenium.DevTools.V120.Log; // 初始化普通ChromeDriver var chromeOptions = new ChromeOptions(); using var driver = new ChromeDriver(chromeOptions); // 开启DevTools会话 var devTools = driver as IDevTools; var devToolsSession = devTools.GetDevToolsSession(); // 启用日志域 await devToolsSession.SendCommand(new EnableCommandSettings()); // 绑定日志新增事件回调 devToolsSession.Domains.Log.EntryAdded += (sender, e) => { Console.WriteLine($"[{e.Level}] [{e.Timestamp.ToDateTime():HH:mm:ss.fff}] {e.Text}"); }; // 执行业务逻辑 driver.Navigate().GoToUrl("你的目标网站地址");
内容的提问来源于stack exchange,提问作者Lázár Zsolt
相关产品推荐
相关产品推荐

