You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 09:34:34