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

如何通过控制台列出网站中使用特定字体的所有页面

如何列出网站中使用特定字体的所有页面?

我们的网站使用多种字体,需要统一字体规范并管理字体授权——比如不希望TheSansCE等字体出现在全站,但已知部分页面在用,得找出这些页面。需要实现两种方案:

  • 方案a:筛选出使用特定字体的所有页面,结果格式示例:[example.com/dot-dot - font: Arial, Calibri, example.com/bot-bot - font: Arial, example.com/derp - font: Calibri]
  • 方案b:输入字体名称后,列出对应的页面URL,示例:输入Arial,结果为example.com/dot-dot、example.com/bot-bot

注意:必须统计页面实际使用的字体,而非CSS样式中定义的字体。


现有代码的局限性

目前找到两段代码,但都无法满足需求:

  1. 获取全站所有URL的代码:
var urls = [];

for (var i = document.links.length; i-- > 0;)
  if (document.links[i].hostname === location.hostname)
    urls.push(document.links[i].href);

console.log(urls);

这段代码只能获取站内所有URL,无法关联字体信息。

  1. 获取页面所有字体的代码:
function styleInPage(css, verbose) {
  if (typeof getComputedStyle == "undefined")
    getComputedStyle = function(elem) {
      return elem.currentStyle;
    }

  var who, hoo, val, 
    values = [],
    nodes = document.body.getElementsByTagName('*'),
    L = nodes.length;
    
  for (var i = 0; i < L; i++) {
    who = nodes[i];
    
    if (who.style) {
      hoo = '#' + (who.id || who.nodeName + '(' + i + ')');
      val = who.style.fontFamily || getComputedStyle(who, '')[css];
      
      if (val) {
        if (verbose) values.push([hoo, val]);
        else if (values.indexOf(val) == -1) values.push(val);
      }

      val_before = getComputedStyle(who, ':before')[css];
      
      if (val_before) {
        if (verbose) values.push([hoo, val_before]);
        else if (values.indexOf(val_before) == -1) values.push(val_before);
      }
      
      val_after = getComputedStyle(who, ':after')[css];
      
      if (val_after) {
        if (verbose) values.push([hoo, val_after]);
        else if (values.indexOf(val_after) == -1) values.push(val_after);
      }
    }
  }
  return values;
}

alert(styleInPage('fontFamily')); // returns array:

这段代码只能获取当前页面的字体,无法关联全站URL并批量检测。


可行实现方案

思路核心

要实现需求,需要批量遍历站内URL + 每个URL页面检测实际使用的字体,再将两者关联起来。以下提供两种实用方案:

方案1:浏览器控制台脚本(快速验证)

以下脚本会自动遍历站内链接,打开新标签页检测每个页面的字体,最后输出关联结果:

// 存储结果:键为URL,值为该页面使用的字体集合
const fontPageMap = new Map();
// 已处理的URL,避免重复检测
const processedUrls = new Set();
// 要排查的目标字体(可修改)
const targetFonts = ['TheSansCE', 'Arial'];

// 获取页面实际使用的字体(优化原有字体检测函数)
function getUsedFonts() {
  const computedFonts = new Set();
  const nodes = document.body.querySelectorAll('*');
  
  for (const node of nodes) {
    // 获取元素自身的实际字体
    const fontFamily = window.getComputedStyle(node).fontFamily;
    if (fontFamily) fontFamily.split(',').forEach(f => computedFonts.add(f.trim().replace(/['"]/g, '')));
    
    // 处理伪元素:before
    const beforeFont = window.getComputedStyle(node, ':before').fontFamily;
    if (beforeFont) beforeFont.split(',').forEach(f => computedFonts.add(f.trim().replace(/['"]/g, '')));
    
    // 处理伪元素:after
    const afterFont = window.getComputedStyle(node, ':after').fontFamily;
    if (afterFont) afterFont.split(',').forEach(f => computedFonts.add(f.trim().replace(/['"]/g, '')));
  }
  
  return Array.from(computedFonts);
}

// 处理单个URL的检测
async function processUrl(url) {
  if (processedUrls.has(url)) return;
  processedUrls.add(url);
  
  try {
    const tab = window.open(url, '_blank');
    await new Promise(resolve => setTimeout(resolve, 2000)); // 等待页面加载(可调整时间)
    
    // 在新标签页执行字体检测
    const fonts = tab.eval('(' + getUsedFonts.toString() + ')()');
    fontPageMap.set(url, fonts);
    
    tab.close();
    console.log(`已检测:${url},字体:${fonts.join(', ')}`);
  } catch (err) {
    console.error(`检测失败:${url},错误:${err.message}`);
  }
}

// 开始批量检测
async function startDetection() {
  // 获取站内所有URL(去重)
  const urls = Array.from(new Set(Array.from(document.links).filter(link => link.hostname === location.hostname).map(link => link.href)));
  
  for (const url of urls) {
    await processUrl(url);
  }
  
  // 输出结果:方案a格式
  console.log('=== 所有页面字体统计 ===');
  const resultA = Array.from(fontPageMap).map(([url, fonts]) => `${url} - font: ${fonts.join(', ')}`);
  console.log(resultA);
  
  // 输出结果:方案b格式(按目标字体筛选)
  console.log('=== 目标字体对应页面 ===');
  targetFonts.forEach(font => {
    const pages = Array.from(fontPageMap).filter(([_, fonts]) => fonts.includes(font)).map(([url]) => url);
    console.log(`${font}:${pages.join('、')}`);
  });
}

// 启动检测
startDetection();

使用说明

  1. 打开网站首页,按F12打开控制台
  2. 将上述代码粘贴到控制台,修改targetFonts为你需要排查的字体
  3. 回车执行,脚本会自动打开新标签页检测每个页面,最后输出两种格式的结果

方案2:Puppeteer自动化工具(稳定批量检测)

如果网站页面较多,浏览器脚本可能因弹窗拦截或加载不稳定出错,推荐用Puppeteer编写Node.js脚本实现更可靠的批量检测:

const puppeteer = require('puppeteer');
const fs = require('fs');

// 配置参数
const baseUrl = 'https://your-website.com'; // 替换为你的网站域名
const targetFonts = ['TheSansCE', 'Arial']; // 要排查的字体

// 获取页面实际使用的字体
async function getPageFonts(page) {
  return page.evaluate(() => {
    const computedFonts = new Set();
    const nodes = document.body.querySelectorAll('*');
    
    for (const node of nodes) {
      const fontFamily = window.getComputedStyle(node).fontFamily;
      if (fontFamily) fontFamily.split(',').forEach(f => computedFonts.add(f.trim().replace(/['"]/g, '')));
      
      const beforeFont = window.getComputedStyle(node, ':before').fontFamily;
      if (beforeFont) beforeFont.split(',').forEach(f => computedFonts.add(f.trim().replace(/['"]/g, '')));
      
      const afterFont = window.getComputedStyle(node, ':after').fontFamily;
      if (afterFont) afterFont.split(',').forEach(f => computedFonts.add(f.trim().replace(/['"]/g, '')));
    }
    
    return Array.from(computedFonts);
  });
}

// 递归爬取站内URL(去重)
async function crawlUrls(page, url, visited = new Set()) {
  if (visited.has(url)) return;
  visited.add(url);
  
  try {
    await page.goto(url, { waitUntil: 'networkidle2' });
    
    // 获取当前页面所有站内链接
    const pageUrls = await page.evaluate(baseUrl => {
      return Array.from(document.links)
        .filter(link => link.hostname === new URL(baseUrl).hostname)
        .map(link => link.href)
        .filter(href => href.startsWith(baseUrl));
    }, baseUrl);
    
    // 递归处理每个链接
    for (const pageUrl of pageUrls) {
      await crawlUrls(page, pageUrl, visited);
    }
  } catch (err) {
    console.error(`爬取失败:${url},错误:${err.message}`);
  }
  
  return visited;
}

// 批量检测页面字体
async function startBatchDetection() {
  const browser = await puppeteer.launch({ headless: false }); // 设为true则无界面运行
  const page = await browser.newPage();
  
  // 爬取所有站内URL
  console.log('开始爬取站内URL...');
  const allUrls = await crawlUrls(page, baseUrl);
  console.log(`共爬取到 ${allUrls.size} 个页面`);
  
  // 检测每个页面的字体
  const fontPageMap = new Map();
  for (const url of allUrls) {
    try {
      await page.goto(url, { waitUntil: 'networkidle2' });
      const fonts = await getPageFonts(page);
      fontPageMap.set(url, fonts);
      console.log(`已检测:${url},字体:${fonts.join(', ')}`);
    } catch (err) {
      console.error(`检测失败:${url},错误:${err.message}`);
    }
  }
  
  // 生成结果文件
  const resultA = Array.from(fontPageMap).map(([url, fonts]) => `${url} - font: ${fonts.join(', ')}`);
  const resultB = targetFonts.reduce((acc, font) => {
    acc[font] = Array.from(fontPageMap).filter(([_, fonts]) => fonts.includes(font)).map(([url]) => url);
    return acc;
  }, {});
  
  fs.writeFileSync('font-page-result-a.txt', resultA.join('\n'));
  fs.writeFileSync('font-page-result-b.json', JSON.stringify(resultB, null, 2));
  
  console.log('检测完成,结果已保存到font-page-result-a.txt和font-page-result-b.json');
  
  await browser.close();
}

// 启动检测
startBatchDetection();

使用说明

  1. 确保已安装Node.js和Puppeteer:npm install puppeteer
  2. 修改baseUrl和targetFonts为你的网站和目标字体
  3. 运行脚本:node font-detector.js
  4. 脚本会自动爬取所有页面并检测字体,最后生成两个结果文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 02:25:51