Java环境下Selenium Driver未等待Mermaid.js页面渲染完成的问题解决咨询
Java环境下Selenium Driver未等待Mermaid.js页面渲染完成的问题解决咨询
针对你遇到的Selenium未等待Mermaid.js渲染完成就获取页面源码的问题,核心原因是Mermaid的图表渲染是异步过程——你当前的等待逻辑只判断了页面的document.readyState为complete,这仅能说明页面资源加载完成,但Mermaid的图表解析、SVG生成还在后台进行,所以会拿到空的<g>标签内容。
下面给你两个可靠的解决思路,结合你的代码给出具体修改方案:
方案一:通过JavaScript直接等待Mermaid渲染完成
Mermaid官方提供了mermaid.run()方法,它会返回一个Promise,当所有图表渲染完成时这个Promise会自动resolve。我们可以在Selenium中执行这段JavaScript,等待它完成后再获取页面源码。
修改你的Java代码
以Edge浏览器的代码分支为例,在driver.get(urlStr)之后新增等待逻辑:
try { driver = new EdgeDriver(options); if (useWait) { waitForPageToLoad(driver, until); } driver.manage().timeouts().implicitlyWait(until); driver.manage().timeouts().pageLoadTimeout(until); var dmn = new Dimension(1280, 1024); driver.manage().window().setSize(dmn); driver.get(urlStr); // 新增:等待Mermaid所有图表渲染完成 WebDriverWait mermaidWait = new WebDriverWait(driver, until); try { mermaidWait.until((ExpectedCondition<Boolean>) driver1 -> { JavascriptExecutor js = (JavascriptExecutor) driver1; // 执行JS等待Mermaid渲染完成,并验证SVG有实际内容 return (Boolean) js.executeScript(""" // 先确保Mermaid模块已加载完成 if (typeof mermaid === 'undefined') return false; // 调用mermaid.run()等待所有图表渲染完成 return mermaid.run().then(() => { // 额外验证SVG的g标签是否有子元素(确保图表真的渲染成功) const svgGroup = document.querySelector('.mermaid svg g'); return svgGroup && svgGroup.children.length > 0; }).catch(err => { console.error('Mermaid渲染失败:', err); return false; }); """); }); } catch (TimeoutException e) { out.println("Mermaid图表渲染超时,请检查网络或Mermaid配置"); throw e; } return driver.getPageSource(); } finally { if (driver != null) { driver.close(); driver.quit(); } }
方案二:在HTML中标记Mermaid渲染完成状态
如果你希望更直观地控制渲染状态,可以修改HTML代码,用全局变量标记Mermaid的渲染完成状态,再在Selenium中等待这个标记触发。
第一步:修改HTML的Script部分
<script type="module"> import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11.4.1/+esm' const config = { startOnLoad: true, flowchart: { useMaxWidth: true, htmlLabels: true, curve: 'cardinal' }, securityLevel: 'loose', }; mermaid.initialize(config); // 新增:全局变量标记Mermaid渲染状态 window.mermaidRenderCompleted = false; // 等待所有图表渲染完成后更新标记 mermaid.run().then(() => { window.mermaidRenderCompleted = true; }).catch(err => { console.error('Mermaid渲染出错:', err); window.mermaidRenderCompleted = true; // 出错也标记,避免无限等待 }); </script>
第二步:修改Java代码中的等待逻辑
在driver.get(urlStr)之后,新增等待全局变量的逻辑:
// 新增:等待Mermaid渲染完成标记 WebDriverWait mermaidWait = new WebDriverWait(driver, until); mermaidWait.until((ExpectedCondition<Boolean>) driver1 -> { JavascriptExecutor js = (JavascriptExecutor) driver1; return (Boolean) js.executeScript("return window.mermaidRenderCompleted === true;"); });
为什么原来的等待逻辑无效?
你之前的waitForPageToLoad方法只判断了document.readyState === 'complete',这个状态仅表示:
- 页面的HTML、CSS、JS等静态资源已加载完成
- 页面的基础DOM树已构建完成
但Mermaid的图表渲染是资源加载完成后才启动的异步任务,它需要解析流程图语法、生成SVG节点,这个过程不在document.readyState的覆盖范围内,所以必须单独等待Mermaid的渲染完成事件。
备注:内容来源于stack exchange,提问作者Tugalsan Karabacak
相关产品推荐
相关产品推荐

