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

如何用Node.js获取指定URL下所有元素的CSS?并编写爬虫检测页面字体

嘿,我来帮你搞定这两个Node.js相关的问题!

1. 如何用Node.js获取指定URL下所有元素的CSS样式?

首先得明确:Node.js本身没有浏览器的渲染环境,像cheerio这类HTML解析库只能拿到元素的内联样式,没法获取最终计算后的CSS样式(比如外部样式表、继承的样式、媒体查询生效后的样式)。所以最靠谱的方案是用无头浏览器工具(比如Puppeteer),它能模拟真实浏览器渲染页面,完美获取每个元素的最终样式。

具体实现步骤

  1. 先安装依赖:
npm install puppeteer
  1. 编写脚本:
const puppeteer = require('puppeteer');

async function getAllElementStyles(url) {
  // 启动无头浏览器
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  
  // 访问目标URL,等待网络空闲确保样式加载完成
  await page.goto(url, { waitUntil: 'networkidle2' });
  
  // 在浏览器上下文执行代码,获取所有元素的计算样式
  const elementStyles = await page.evaluate(() => {
    const elements = Array.from(document.querySelectorAll('*'));
    return elements.map(element => {
      const computedStyle = window.getComputedStyle(element);
      // 生成元素的简易选择器,方便识别
      const selector = element.id ? `#${element.id}` : 
                      element.className ? `.${element.className.replace(/\s+/g, '.')}` :
                      element.tagName.toLowerCase();
      // 提取所有计算后的样式属性
      const styles = Object.fromEntries(
        Array.from(computedStyle).map(prop => [prop, computedStyle[prop]])
      );
      
      return { tagName: element.tagName, selector, styles };
    });
  });
  
  await browser.close();
  return elementStyles;
}

// 使用示例
getAllElementStyles('http://example.com')
  .then(styles => console.log('所有元素的计算样式:', styles))
  .catch(err => console.error('出错了:', err));

如果只需要特定样式属性(比如font-family),可以在styles里只提取需要的字段,减少返回的数据量。


2. 完善遍历链接并检查Helvetica字体的脚本

你原来用request和cheerio的思路没问题,但这两个工具没法处理CSS渲染,根本拿不到元素实际使用的字体。同样得换成Puppeteer,它能准确获取每个元素计算后的字体。我帮你完善了完整脚本:

步骤1:安装依赖

npm install puppeteer url-parse

步骤2:完整脚本

const puppeteer = require('puppeteer');
const URL = require('url-parse');

const START_URL = "http://example.com/";
const SEARCH_FONT = "helvetica";
const MAX_PAGES_TO_VISIT = 100000;
const pagesVisited = new Set(); // 用Set存储已访问页面,避免重复爬取
let numPagesVisited = 0;
const pagesToVisit = [START_URL];

async function checkPageForFont(pageUrl) {
  const browser = await puppeteer.launch({ headless: 'new' });
  const page = await browser.newPage();
  
  try {
    // 访问页面,设置超时避免卡住
    await page.goto(pageUrl, { waitUntil: 'networkidle2', timeout: 30000 });
    console.log(`正在检查页面: ${pageUrl}`);
    
    // 检查页面是否有元素使用Helvetica字体
    const hasHelvetica = await page.evaluate((targetFont) => {
      const elements = Array.from(document.querySelectorAll('*'));
      return elements.some(element => {
        const computedFont = window.getComputedStyle(element).fontFamily.toLowerCase();
        return computedFont.includes(targetFont.toLowerCase());
      });
    }, SEARCH_FONT);
    
    // 输出检查结果
    if (hasHelvetica) {
      console.log(`✅ 页面 ${pageUrl} 发现使用了 ${SEARCH_FONT} 字体`);
    } else {
      console.log(`❌ 页面 ${pageUrl} 未发现使用 ${SEARCH_FONT} 字体`);
    }
    
    // 提取页面中所有有效链接
    const pageLinks = await page.evaluate(() => {
      return Array.from(document.querySelectorAll('a[href]')).map(a => a.href);
    });
    
    await browser.close();
    return pageLinks;
  } catch (err) {
    console.error(`访问页面 ${pageUrl} 出错:`, err.message);
    await browser.close();
    return [];
  }
}

async function crawl() {
  while (numPagesVisited < MAX_PAGES_TO_VISIT && pagesToVisit.length > 0) {
    const currentUrl = pagesToVisit.shift();
    
    // 跳过已访问页面或非HTTP链接
    if (pagesVisited.has(currentUrl) || !currentUrl.startsWith('http')) {
      continue;
    }
    
    pagesVisited.add(currentUrl);
    numPagesVisited++;
    
    // 检查当前页面字体,并提取新链接
    const links = await checkPageForFont(currentUrl);
    
    // 过滤同域名链接(可选,避免爬取范围过大)
    const parsedStartUrl = new URL(START_URL);
    links.forEach(link => {
      const parsedLink = new URL(link);
      if (parsedLink.host === parsedStartUrl.host && !pagesVisited.has(parsedLink.href)) {
        pagesToVisit.push(parsedLink.href);
      }
    });
  }
  
  console.log(`爬取完成!共访问了 ${numPagesVisited} 个页面`);
}

// 启动爬取
crawl();

脚本说明

  • 用Set存储已访问页面,比普通对象更高效,避免重复爬取
  • 加入超时设置,防止某个页面加载过慢导致脚本卡住
  • 可选过滤同域名链接,避免无限制爬取整个互联网(如果需要跨域名,去掉这个逻辑即可)
  • 每个页面检查后会清晰输出结果,方便你快速定位使用Helvetica的页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:23:55