C# Selenium4.0.0-beta4 IDevTools无CreateDevToolsSession如何解决
问题根因
- 方法更名:
CreateDevToolsSession()是Selenium 4.0.0-beta3及更早版本的API,你使用的beta4版本已经将该方法废弃,替换为GetDevToolsSession(),所有旧教程的代码均针对更早的beta版本编写,因此会出现方法不存在的问题。 - 窗体冻结原因:
GetDevToolsSession()调用时会和Chrome内核完成调试协议握手,是耗时阻塞操作。你直接在UI线程同步调用该方法,会阻塞UI消息循环,导致窗体无响应、后续代码不执行。
解决方案
调整代码逻辑,将DevTools初始化和监听逻辑放到异步后台线程执行,同时修复请求拦截的常见逻辑缺陷,修正后代码如下:
using V89 = OpenQA.Selenium.DevTools.V89; using V89Net = OpenQA.Selenium.DevTools.V89.Network; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.DevTools; using System.Threading.Tasks; ChromeOptions options = new ChromeOptions(); ChromeDriver webDriver; IDevTools devTools; V89.Fetch.FetchAdapter fetch; public async void InterceptRequestWithFetch(string url) { // 后台异步执行初始化逻辑,避免阻塞UI await Task.Run(() => { options.BinaryLocation = @"C:\Program Files\Google\Chrome Beta\Application\chrome.exe"; var service = ChromeDriverService.CreateDefaultService(); service.LogPath = AppDomain.CurrentDomain.BaseDirectory + "chromedriver.log"; service.EnableVerboseLogging = true; webDriver = new ChromeDriver(service, options); devTools = webDriver as IDevTools; // 调用beta4版本提供的GetDevToolsSession方法 var devToolsSession = devTools.GetDevToolsSession(); fetch = devToolsSession.GetVersionSpecificDomains<V89.DevToolsSessionDomains>().Fetch; var enableCommandSettings = new V89.Fetch.EnableCommandSettings(); var requestPattern = new V89.Fetch.RequestPattern(); requestPattern.RequestStage = V89.Fetch.RequestStage.Response; // 如果你要匹配jpg资源,建议修改ResourceType为Image,XHR类型通常不会返回jpg资源 requestPattern.ResourceType = V89Net.ResourceType.Image; requestPattern.UrlPattern = "*://*/*.jpg*"; enableCommandSettings.Patterns = new V89.Fetch.RequestPattern[] { requestPattern }; fetch.Enable(enableCommandSettings); fetch.RequestPaused += RequestIntercepted; }); webDriver.Navigate().GoToUrl(url); } async void RequestIntercepted(object sender, V89.Fetch.RequestPausedEventArgs e) { // 跨线程更新UI控件需要用Invoke避免异常 richTextBox1.Invoke(new Action(() => { richTextBox1.AppendText(e.Request.Url + Environment.NewLine); })); // 必须调用ContinueRequest,否则请求会一直挂起,导致页面卡住 await fetch.ContinueRequestAsync(new V89.Fetch.ContinueRequestCommandSettings() { RequestId = e.RequestId }); // 测试阶段不要直接在拦截事件里退出Driver,会导致会话异常,调试通过后再调整退出逻辑 // webDriver.Quit(); }
注意事项
- 必须保证Chrome浏览器大版本和你引用的DevTools协议版本一致,本代码用的V89协议,对应的Chrome大版本必须是89,否则会出现协议不兼容错误
- 拦截到请求后必须调用
ContinueRequestAsync放行请求,否则所有匹配到的请求会一直处于挂起状态,导致页面加载失败 - 如果需要匹配XHR类型的请求,调整UrlPattern和ResourceType的对应关系即可
内容的提问来源于stack exchange,提问作者iѕєρєня
相关产品推荐
相关产品推荐

