Node.js 全站死链检测工具:从 sitemap 出发一次找全 404

Node.js 全站死链检测工具:从 sitemap 出发一次找全 404

做独立站,死链是排名和体验的双重杀手。买家点进一个链接结果是 404,马上关掉;谷歌爬虫反复撞到 404,会拉低对整个站的抓取效率和信任。站子一大,几十上百页里哪些链接已经失效,人工点一遍不现实。这篇写一个 Node.js 工具,从 sitemap 出发,把全站所有 URL 的返回状态一次查清,死链直接列出来。

sitemap 的官方说明在这里:Google sitemap 指南,链接要能被抓取的原则看这篇:可抓取的链接。

工具能检查什么

  1. 解析 sitemap(支持 sitemap index 嵌套)
  2. 并发请求每个 URL,记录 HTTP 状态码
  3. 分类:200 正常、3xx 重定向、404 死链、5xx 服务器错误、超时
  4. 输出死链清单,直接照着修

这个版本用 Node.js 原生 fetch,不需要装任何第三方依赖,Node 18 及以上直接跑。

完整代码

javascript 复制代码
// deadlink-checker.js
// 用途:从 sitemap 出发,检查全站 URL 的返回状态,找出死链
// 运行:node deadlink-checker.js https://example.com/sitemap.xml
// 依赖:无(Node 18+ 自带 fetch)

const CONCURRENCY = 10; // 并发数,太大容易被目标站限流

function decodeEntities(s) {
  return s
    .replace(/&/g, '&')
    .replace(/&lt;/g, '<')
    .replace(/&gt;/g, '>')
    .replace(/&quot;/g, '"')
    .replace(/&#39;/g, "'");
}

async function fetchStatus(url) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), 10000); // 10 秒超时
  try {
    const res = await fetch(url, {
      method: 'GET',
      redirect: 'manual', // 手动处理,才能拿到 301/302 本身
      signal: controller.signal,
      headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0 Safari/537.36' },
    });
    if (res.type === 'opaqueredirect') return 302;
    return res.status;
  } catch (e) {
    return e.name === 'AbortError' ? 'TIMEOUT' : 'ERROR';
  } finally {
    clearTimeout(timer);
  }
}

async function parseSitemap(url, urls = []) {
  const status = await fetchStatus(url);
  if (status !== 200) return urls;
  const text = await (await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } })).text();
  const locs = [...text.matchAll(/<loc>([^<]+)<\/loc>/g)].map((m) => decodeEntities(m[1].trim()));
  for (const loc of locs) {
    if (loc.endsWith('.xml')) {
      await parseSitemap(loc, urls); // sitemap index 嵌套,递归解析
    } else {
      urls.push(loc);
    }
  }
  return urls;
}

async function main(sitemapUrl) {
  console.log(`解析 sitemap: ${sitemapUrl}\n` + '='.repeat(60));
  const urls = await parseSitemap(sitemapUrl);
  const unique = [...new Set(urls)];
  if (!unique.length) {
    console.log('sitemap 解析失败或没有 URL');
    return;
  }
  console.log(`共 ${unique.length} 个页面,开始并发检查...\n`);

  const results = { ok: [], redirect: [], notFound: [], serverError: [], other: [] };
  const queue = [...unique];
  const workers = Array.from({ length: CONCURRENCY }, async () => {
    while (queue.length) {
      const url = queue.shift();
      const status = await fetchStatus(url);
      if (status === 200) results.ok.push(url);
      else if ([301, 302, 307, 308].includes(status)) results.redirect.push({ url, status });
      else if (status === 404) results.notFound.push(url);
      else if (typeof status === 'number' && status >= 500) results.serverError.push({ url, status });
      else results.other.push({ url, status });
    }
  });
  await Promise.all(workers);

  console.log('='.repeat(60));
  console.log(`正常 200: ${results.ok.length}`);
  console.log(`重定向 3xx: ${results.redirect.length}`);
  console.log(`死链 404: ${results.notFound.length}`);
  console.log(`服务器错误 5xx: ${results.serverError.length}`);
  console.log(`其他: ${results.other.length}`);

  if (results.notFound.length) {
    console.log('\n死链清单:');
    results.notFound.forEach((u) => console.log('  404  ' + u));
  }
  if (results.redirect.length) {
    console.log('\n重定向清单:');
    results.redirect.forEach((r) => console.log(`  ${r.status}   ${r.url}`));
  }
  if (results.serverError.length) {
    console.log('\n服务器错误清单:');
    results.serverError.forEach((r) => console.log(`  ${r.status}   ${r.url}`));
  }
  console.log('\n检查结束。');
}

const target = process.argv[2] || 'https://example.com/sitemap.xml';
main(target);

怎么用

bash 复制代码
node deadlink-checker.js https://你的域名/sitemap.xml

把最后的地址换成你自己的 sitemap,运行。它会自动跟进嵌套的 sitemap index,把全站页面都查一遍,最后按状态码分类输出。

三个最常见的死链来源

产品下架但页面没处理。 外贸站产品经常上新下架,下架的产品如果直接删掉、没做 301 或没删内链,就留下一个 404。这些页面积累起来,站里就到处是坑。

换域名或改 URL 结构。 站点改版、换域名的过程中,老 URL 如果没做重定向,等于把之前积累的权重和收录全部扔了,还制造一批死链。

外链和内链指向了不存在的地址。 有些死链来自站内文章的旧链接,有些来自别处引用了你已经删掉的页面。前者你能自己修,后者要看情况做 301 或保留页面。

写在最后

死链检测门槛不高,难在定期做。站子一更新,就会冒出新的死链,建议每个月跑一次,把清单里的 404 逐个处理掉。觉得有用欢迎点赞、收藏、转发,有疑问评论区留言或私信交流。

相关推荐
用户8356290780516 分钟前
Python 如何在 Word 中添加和管理文档变量
后端·python
X1A0RAN18 分钟前
PPT 图片批量处理教程:导出全部幻灯片 · 提取全部素材
开发语言·javascript·powerpoint
张彦峰ZYF26 分钟前
浏览器调试接口的官方化:从 chrome-devtools-mcp 看 Agent 原生工具层的形成
人工智能·chrome·agent·mcp·apache-2.0许可·devtools-mcp·调试闭环
Dawson Zhu42 分钟前
Queen Planner深度解析:Agent竞争从模型时代进入系统时代
人工智能·语言模型·架构·aigc·agi
甲维斯1 小时前
GPT6.2Astra也很强啊,国模...!
人工智能
承渊政道1 小时前
Fooocus本地AI绘图教程:Windows部署、低门槛生图与远程访问
人工智能·windows·cpolar·fooocus·生图
熊猫钓鱼>_>2 小时前
普通用户视角的端侧智能体验手记【鸿蒙心迹】
开发语言·人工智能·华为·智能手机·性能优化·ai编程·harmonyos
瑞雪兆丰年兮2 小时前
JavaWeb-day13-SpringBootWeb事务管理&AOP
java·开发语言·springboot·javaweb·事务·web·aop
AI算力2 小时前
私有云时代来临:AI NAS如何重塑你的数字生活?
人工智能·科技·ai·生活·nas·ai算力·ainas
程序员cxuan2 小时前
讲真,智能路由这事儿,还得看基元律动
人工智能·后端·程序员