本地运行正常的Selenium在Azure部署后抛出异常问题排查
问题根源
异常信息明确指出磁盘空间不足(os error 112),原因是Azure App Service的临时存储配额有限,而Selenium Manager自动下载Chrome浏览器/驱动、Chrome运行时产生的缓存/临时文件占用了过多空间,导致无法完成初始化。
解决方案
1. 优化Chrome启动参数,削减磁盘占用
修改ChromeOptions,添加限制缓存、禁用冗余功能的参数,减少磁盘写入:
var options = new ChromeOptions(); // 新版无头模式,资源占用远低于旧版 options.AddArgument("--headless=new"); options.AddArgument("--disable-gpu"); options.AddArgument("--no-sandbox"); options.AddArgument("--disable-dev-shm-usage"); // 彻底禁用缓存,避免磁盘写入 options.AddArgument("--disable-cache"); options.AddArgument("--disk-cache-size=0"); // 隐身模式,不存储任何用户数据 options.AddArgument("--incognito"); // 禁用扩展、插件,减少资源消耗 options.AddArgument("--disable-extensions"); options.AddArgument("--disable-plugins"); // 单进程运行,降低内存与磁盘占用 options.AddArgument("--single-process"); // 缩小窗口尺寸,降低渲染负载 options.AddArgument("--window-size=800,600");
2. 禁止Selenium Manager自动下载浏览器
Selenium Manager默认会下载完整Chrome浏览器到临时目录,这是磁盘占用的核心原因之一。可以通过以下两种方式规避:
方式一:使用Azure Site Extensions预装的Chrome
- 登录Azure门户,进入你的App Service
- 在左侧菜单选择开发工具 > 站点扩展,搜索并安装Headless Chrome扩展
- 在代码中指定Chrome二进制文件路径:
options.BinaryLocation = @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe";
方式二:手动部署ChromeDriver
将ChromeDriver提前上传到应用的wwwroot目录,代码中直接指定驱动路径:
var driverDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "chromedriver"); using IWebDriver driver = new ChromeDriver(driverDir, options);
3. 清理Azure App Service磁盘空间
- 进入App Service概述页面,查看当前磁盘使用情况
- 清理部署中心的旧部署历史记录
- 开启日志 > 应用日志的自动清理功能,定期删除过期日志
- 若使用Free/Basic层级,考虑升级到Standard层级以获得更大磁盘配额
4. 优化代码中的等待逻辑
替换低效的Thread.Sleep为WebDriverWait,精准等待目标元素加载,减少Chrome运行时长:
// 等待页面中至少存在3个canvas元素 var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(3)); wait.Until(d => d.FindElements(By.TagName("canvas")).Count >= 3); // 执行JavaScript获取Data URL IJavaScriptExecutor js = (IJavaScriptExecutor)driver; string script = @"var canvasList = document.querySelectorAll('canvas'); return canvasList[2].toDataURL('image/png');"; string dataUrl = (string)js.ExecuteScript(script);
5. 确保Driver资源完全释放
虽然using语句会自动释放资源,但建议在finally块中显式关闭driver,避免残留进程占用资源:
IWebDriver driver = null; try { driver = new ChromeDriver(options); driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5); driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5); driver.Navigate().GoToUrl(YahooAnalysisURL(ticker)); var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(3)); wait.Until(d => d.FindElements(By.TagName("canvas")).Count >= 3); IJavaScriptExecutor js = (IJavaScriptExecutor)driver; string script = @"var canvasList = document.querySelectorAll('canvas'); return canvasList[2].toDataURL('image/png');"; string dataUrl = (string)js.ExecuteScript(script); return dataUrl; } catch (WebDriverTimeoutException) { // 处理超时逻辑 return string.Empty; } finally { driver?.Quit(); driver?.Dispose(); }
额外提示
Yahoo Finance存在反爬机制,频繁请求可能导致IP被封禁,建议添加请求间隔、合理控制调用频率。
内容的提问来源于stack exchange,提问作者user3575705
相关产品推荐
相关产品推荐

