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

Selenium如何获取Rendered Fonts板块中的实际渲染字体名称

Selenium检测实际渲染字体实现方案

Selenium原生的element.getCssValue("font-family")只能读取CSS中声明的字体栈配置,无法拿到浏览器排版后实际生效的渲染字体,要获取DevTools Elements面板Computed标签下Rendered Fonts板块的内容,直接调用Chrome DevTools Protocol(CDP)对应接口即可,返回数据和DevTools展示的内容完全一致。

核心原理

Rendered Fonts板块的所有数据来自CDP暴露的CSS.getPlatformFontsForNode接口,传入目标DOM节点的ID,就能直接返回该节点文本渲染时实际调用的所有系统字体列表,字体加载失败触发fallback的情况会被完整记录。

注意:不存在Rendered Fonts板块完全无条目的场景,只要元素可见、参与页面排版,该区域一定会展示最终生效的渲染字体。你需要校验的是列表中是否存在非预期的替代字体(比如Times New Roman),而非判断列表是否为空。

Java代码实现(Selenium 4+ 原生支持,无需额外依赖)

import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class FontCheckUtil {
    /**
     * 检测元素实际渲染字体,存在非预期 fallback 时抛出错误
     * @param driver ChromeDriver实例(Edge等Chromium内核浏览器通用)
     * @param target 待检测的页面元素
     * @param expectedFont 预期生效的字体名称
     */
    public void assertNoFontFallback(ChromeDriver driver, WebElement target, String expectedFont) {
        // 1. 获取目标元素在CDP中的nodeId
        Map<String, Object> evalParams = new HashMap<>();
        evalParams.put("expression", "arguments[0]");
        evalParams.put("objectGroup", "font-check");
        evalParams.put("includeCommandLineAPI", Boolean.TRUE);
        Map<String, Object> evalArgs = new HashMap<>();
        evalArgs.put("0", target);
        evalParams.put("arguments", List.of(evalArgs));
        Map<String, Object> evalResult = driver.executeCdpCommand("Runtime.evaluate", evalParams);
        String objectId = (String) ((Map<String, Object>) evalResult.get("result")).get("objectId");

        Map<String, Object> nodeReqParams = new HashMap<>();
        nodeReqParams.put("objectId", objectId);
        Map<String, Object> nodeResult = driver.executeCdpCommand("DOM.requestNode", nodeReqParams);
        Number nodeId = (Number) nodeResult.get("nodeId");

        // 2. 拉取实际渲染字体列表
        Map<String, Object> fontQueryParams = new HashMap<>();
        fontQueryParams.put("nodeId", nodeId);
        Map<String, Object> fontResult = driver.executeCdpCommand("CSS.getPlatformFontsForNode", fontQueryParams);
        List<Map<String, Object>> renderedFonts = (List<Map<String, Object>>) fontResult.get("fonts");

        // 3. 校验逻辑
        for (Map<String, Object> font : renderedFonts) {
            String actualFamily = (String) font.get("familyName");
            if (!expectedFont.equals(actualFamily)) {
                throw new AssertionError(String.format(
                    "检测到字体替代渲染:预期字体%s未正常加载,实际生效字体为%s",
                    expectedFont, actualFamily
                ));
            }
        }
    }
}

使用注意事项

  • 必须等页面字体加载流程完成(含浏览器字体加载超时触发fallback的时间)后再调用检测方法,否则会拿到加载中间态的错误结果
  • 不要对display:none、visibility:hidden等脱离排版流的隐藏元素做检测,这类元素不会触发字体排版计算,返回结果无效
  • 如果使用Firefox浏览器,需要替换为对应版本的Marionette协议接口,逻辑一致仅接口命名有差异

内容的提问来源于stack exchange,提问作者S P

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 15:36:16