如何通过控制台列出网站中使用特定字体的所有页面
如何列出网站中使用特定字体的所有页面?
我们的网站使用多种字体,需要统一字体规范并管理字体授权——比如不希望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样式中定义的字体。
现有代码的局限性
目前找到两段代码,但都无法满足需求:
- 获取全站所有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,无法关联字体信息。
- 获取页面所有字体的代码:
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();
使用说明
- 打开网站首页,按F12打开控制台
- 将上述代码粘贴到控制台,修改
targetFonts为你需要排查的字体 - 回车执行,脚本会自动打开新标签页检测每个页面,最后输出两种格式的结果
方案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();
使用说明
- 确保已安装Node.js和Puppeteer:
npm install puppeteer - 修改
baseUrl和targetFonts为你的网站和目标字体 - 运行脚本:
node font-detector.js - 脚本会自动爬取所有页面并检测字体,最后生成两个结果文件
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

