Selenium ChromeDriver executeScript与浏览器控制台结果不一致问题
解决Selenium访问Chrome下载页shadow DOM报错的问题
核心原因
你遇到的Cannot read properties of null (reading 'shadowRoot')错误,本质是两个问题:
- Selenium执行脚本时,当前页面未必是
chrome://downloads,或者页面还没完全渲染完成,目标元素还未生成 - Chrome内部页面的shadow DOM结构加载有延迟,直接执行脚本会拿不到元素
解决方案步骤
1. 先切换到下载页并等待页面加载完成
不要直接执行JS脚本,先主动跳转到下载页,并用显式等待确保页面核心元素加载完毕:
// 跳转到Chrome下载页面 driver.get("chrome://downloads"); // 显式等待下载页的根容器加载(最多等10秒) WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(driver -> ((JavascriptExecutor) driver).executeScript( "return document.querySelector('downloads-manager') !== null;" ));
2. 调整JS脚本,逐层访问shadow DOM并增加容错
Chrome下载页的shadow DOM层级是downloads-manager → downloads-item,需要逐层获取shadowRoot,同时增加判断避免空指针:
// 执行JS脚本获取最新下载的文件名 String latestFileName = (String) ((JavascriptExecutor) driver).executeScript(""" // 逐层获取shadow DOM const manager = document.querySelector('downloads-manager'); if (!manager) return null; const managerShadow = manager.shadowRoot; if (!managerShadow) return null; const item = managerShadow.querySelector('downloads-item:last-of-type'); if (!item) return null; const itemShadow = item.shadowRoot; if (!itemShadow) return null; // 获取文件名元素 const nameElement = itemShadow.querySelector('.name'); return nameElement ? nameElement.textContent.trim() : null; """); // 输出结果 if (latestFileName != null) { System.out.println("最新下载文件名:" + latestFileName); } else { System.out.println("未找到下载记录"); }
3. 额外注意事项
- 确保ChromeDriver和Chrome版本完全匹配(你当前版本是匹配的,这点没问题)
- 如果下载是在新标签页触发的,要先切换回下载页所在的标签页
- 可以给下载操作增加等待,确保文件开始下载后再去获取文件名(比如等待下载图标出现)
内容的提问来源于stack exchange,提问作者mmo
相关产品推荐
相关产品推荐

