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 逐个处理掉。觉得有用欢迎点赞、收藏、转发,有疑问评论区留言或私信交流。

相关推荐
张彦峰ZYF1 小时前
让 Agent 获得“手、脚与反射弧”: MHS 如何重构物理世界的长程自主化基础设施
人工智能·ai agent·mhs·可复用能力·治理、记忆、持久编排·工具路由和物理执行·长程agent五平面架构
ljt27249606611 小时前
Python笔记(九)--asyncio
笔记·python
AI棒棒牛1 小时前
基于 IDEAL 思想的 YOLO26 双分支适配:差异证据与不确定性门控,RGB+IR双分支创新!
人工智能·深度学习·yolo·目标检测·yolo26
xiongmosy1 小时前
声网创始人兼CEO赵斌:对话AGI的终点,是“理解一个人”
人工智能·agi
瓶瓶持续学习中1 小时前
数字孪生到空间智能,5家厂商的技术路线有何不同?
大数据·人工智能·信息可视化·架构
neocheng_5221 小时前
不能固定时间上课,可以考哪些AI证书?
人工智能
喜欢打篮球的普通人1 小时前
LLVM 架构设计与原理:为什么它能取代 GCC 成为新宠
c语言·开发语言
老孟说禅1 小时前
自动化测试实战(二)
python