如何用Selenium C#从Agnostic Grid读取数据到List<string>
解决方案:Selenium C# 读取Agnostic Grid全量列数据
核心思路
Agnostic Grid采用虚拟列渲染机制,仅生成可见区域的列DOM元素,因此必须通过逐步滚动采集+数据合并或直接调用AG Grid JavaScript API的方式绕过渲染限制,获取全量数据。
方法一:DOM滚动逐步采集并合并数据
模拟用户滚动行为,每次滚动后采集当前可见列数据,最终按列索引合并全量内容。
// 1. 定位网格核心元素 IWebElement gridContainer = driver.FindElement(By.CssSelector(".ag-center-cols-container")); IWebElement horizontalScroll = driver.FindElement(By.Id("ag-body-horizontal-scroll-container")); IJavaScriptExecutor js = (IJavaScriptExecutor)driver; // 2. 获取所有行 IList<IWebElement> rows = driver.FindElements(By.CssSelector(".ag-center-cols-container [role='row']")); List<List<string>> allRowData = new List<List<string>>(); // 3. 遍历每行采集全量列数据 foreach (IWebElement row in rows) { if (string.IsNullOrWhiteSpace(row.Text)) continue; Dictionary<int, string> columnData = new Dictionary<int, string>(); int lastMaxColIndex = 0; while (true) { // 获取当前行可见列(带aria-colindex属性) IList<IWebElement> visibleCols = row.FindElements(By.CssSelector("[aria-colindex]")); if (visibleCols.Count == 0) break; // 计算当前可见列的最大索引 int currentMaxColIndex = visibleCols.Max(col => int.Parse(col.GetAttribute("aria-colindex"))); if (currentMaxColIndex == lastMaxColIndex) break; // 已滚动至最右侧,停止循环 // 保存当前列数据(按索引去重) foreach (IWebElement col in visibleCols) { int colIndex = int.Parse(col.GetAttribute("aria-colindex")); if (!columnData.ContainsKey(colIndex)) { columnData[colIndex] = col.Text.Trim(); } } // 滚动水平滚动条(每次滚动一个视窗宽度) js.ExecuteScript("arguments[0].scrollLeft += arguments[0].clientWidth;", horizontalScroll); Thread.Sleep(300); // 等待列渲染完成 lastMaxColIndex = currentMaxColIndex; } // 将字典按索引排序,转为行数据List allRowData.Add(columnData.OrderBy(kv => kv.Key).Select(kv => kv.Value).ToList()); } // 4. (可选)按列名映射数据 Dictionary<int, string> columnNames = new Dictionary<int, string>(); IList<IWebElement> headerCols = driver.FindElements(By.CssSelector(".ag-header-row [aria-colindex]")); foreach (IWebElement headerCol in headerCols) { int colIndex = int.Parse(headerCol.GetAttribute("aria-colindex")); columnNames[colIndex] = headerCol.Text.Trim(); } // 生成按列名存储的结构 Dictionary<string, List<string>> columnWiseData = new Dictionary<string, List<string>>(); foreach (var kv in columnNames) { columnWiseData[kv.Value] = allRowData.Select(row => row[kv.Key - 1]).ToList(); }
方法二:直接调用AG Grid JavaScript API(推荐)
利用AG Grid内置API直接获取全量数据,无需处理DOM滚动,稳定性更高。
IJavaScriptExecutor js = (IJavaScriptExecutor)driver; // 1. 执行脚本获取AG Grid全量数据(需替换网格选择器为实际页面的选择器) string gridScript = @" const gridElement = document.querySelector('.ag-grid'); // 替换为你的网格DOM选择器 const gridApi = gridElement.agGrid.api; if (!gridApi) throw new Error('AG Grid API未找到'); return gridApi.getDataAsJson(); // 返回包含列名和行数据的JSON数组 "; // 2. 解析返回的动态数据 var rawData = js.ExecuteScript(gridScript) as IEnumerable<dynamic>; if (rawData == null) throw new InvalidOperationException("获取网格数据失败"); // 3. 整理为按列名存储的List结构 Dictionary<string, List<string>> columnWiseData = new Dictionary<string, List<string>>(); foreach (var row in rawData) { foreach (var prop in ((IDictionary<string, object>)row).Keys) { if (!columnWiseData.ContainsKey(prop)) { columnWiseData[prop] = new List<string>(); } columnWiseData[prop].Add(row[prop]?.ToString() ?? string.Empty); } } // (可选)整理为每行的List<string>结构 List<List<string>> rowWiseData = rawData.Select(row => ((IDictionary<string, object>)row).Values.Select(v => v?.ToString() ?? string.Empty).ToList() ).ToList();
关键注意事项
- 滚动后必须添加等待时间,确保列DOM元素渲染完成
aria-colindex为1-based索引,处理时注意转换为0-based的List索引- AG Grid API版本可能存在差异,需根据实际页面的AG Grid版本调整脚本
- 避免硬编码列数,通过动态获取最大列索引或API获取列定义来确定范围
内容的提问来源于stack exchange,提问作者StackUseR
相关产品推荐
相关产品推荐

