SEO 死链排查实战:那些正在悄悄吃掉你抓取预算的 404
搜索引擎优化里最不性感、但回报最确定的一项工作,是死链排查。它不像内容创作那样有成就感,也不会让你在朋友圈里显得很专业,但它的收益非常实在:每修掉一批 404,爬虫就能把省下来的抓取预算用在你的新文章上。
这篇文章讲的是从日志出发,系统性地找出死链、判断哪些值得修、以及用什么方式修的全套流程。它解决的是一个具体问题:为什么我一直在更新,收录却不涨?
第一步:先从日志里找出真实的 404 请求
不要靠感觉,也不要靠百度搜索资源平台或 Google Search Console 的报告作为唯一来源——那些报告的延迟是几天到几周,而且样本被抽样。最准确的来源是你自己的访问日志。
假设 Nginx 日志是标准 combined 格式,字段顺序是 $remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent",那么找 404 的命令是:
awk '$9 == 404 {print $7}' /var/log/nginx/access.log \
| sort | uniq -c | sort -rn | head -50如果日志压缩过,用 zcat 或 zgrep。如果要覆盖最近 7 天:
zcat -f /var/log/nginx/access.log* \
| awk '$9 == 404 {print $7}' | sort | uniq -c | sort -rn | head -50更进一步,区分谁在请求这些 404,这一步决定了你要不要修。从 UA 里筛出爬虫:
zcat -f /var/log/nginx/access.log* \
| awk '$9 == 404 && $NF ~ /(Googlebot|Baiduspider|bingbot|YandexBot|Sogou)/ {
match($0, /"([^"]*)"$/); ua=substr($0, RSTART, RLENGTH);
print $7" "ua
}' | sort | uniq -c | sort -rn | head -30关键在于:如果 404 只来自某个扫描器,不用管。扫描器每天会请求几百个 /wp-login.php、/.env、/phpmyadmin,这些返回 404 是完全正常且正确的行为,你对它们做任何"修复"都是在给自己挖坑(比如把 /wp-login.php 301 到首页,那是给攻击者送温暖的错误做法)。
真正需要处理的是这三类:
一、你站点自己页面上的内链指向的 404(从 referer 是你的域名的请求里找);
二、搜索引擎爬虫在抓的内链 404;
三、有外部站点正常引用的 404(有价值的外链落空了)。
第二步:区分 404 还是 410,别一律 301 到首页
这是国内 SEO 圈流传最广的错误做法之一:把所有 404 都 301 到首页。理由是"保住权重,不让权重流失"。这个做法在搜索引擎的官方文档里是明确反对的,而且实际危害很大:
当爬虫请求一个不存在的页面 /old-post-123.html,你返回 301 到首页,爬虫会认为这个 URL 已经永久迁移到首页了。如果这样的重定向有几百个,你就在告诉搜索引擎"我有几百个不同的 URL 都指向首页",这会被判定为软 404 甚至低质量信号,首页的权重被稀释,而且爬虫会持续来重复验证这些重定向,白白浪费抓取预算。
正确做法是按 URL 的语义分三类处理:
真正的永久迁移(文章改了 URL、分类结构调整)→ 用 301 指向最相关的那一篇或那个分类页,一对一,不要全部指首页。
内容确实删除了、且没有替代 → 返回 410 Gone。410 是一个被严重低估的状态码,它明确告诉爬虫"这里的东西永久没了,别再来",比 404 更快地把 URL 从索引里移除,能更有效地释放抓取预算。
暂时性故障导致的 404(比如数据库连不上、程序 bug)→ 这才是需要修的,应该修好让页面恢复正常 200,而不是加个重定向掩盖问题。
# Nginx 里精确的一对一重定向
location = /old-post-123.html {
return 301 /new-post-456.html;
}
# 整批删除的路径,返回 410
location ~* ^/tag/(deprecated|old-tag)/ {
return 410;
}
# 全站规则兜底:找不到就 404,绝对不 301 到首页
error_page 404 /404.html;
location = /404.html { internal; }
# 注意:这里不要写 return 301 /;第三步:检查源头——为什么会产出 404
修 404 只是治标,找到产出的源头才是治本。个人站上 404 的高频来源有这么几个,每一个都有对应的检查方法:
改了固定链接结构但没做重定向。Typecho 换 permalink 格式、WordPress 把 ?p=123 改成 /post-name/,都会产生大批 404。检查方法:用 Search Console 的"已发现但未编入索引"和 404 报告交叉比对,找出规则性的一批 URL。修复用 Nginx 正则做批量映射。
附件/图片路径变更。迁移服务器、改了上传目录、换了 CDN,老图片路径全 404。这在日志里会表现为大量 /usr/uploads/... 或 /wp-content/uploads/... 的 404。这类修 404 的意义重大,因为图片链接往往还散落在外部站点上。
站内自己写错的内链。最典型的是手写的绝对链接里域名带 www 或不带,或者指向了已经删掉的标签页。检查方法是在数据库里搜链接:
-- Typecho:找出正文里的站内链接
SELECT cid, title, text FROM typecho_contents
WHERE type='post' AND text LIKE '%你的域名%' LIMIT 20;然后逐条 curl 验证这些内链是否 200。这件事值得做成一个脚本定期跑:抽出全站所有内链,批量发 HEAD 请求,报告非 200 的链接和它所在的文章。我做过一次,在自己只有几百篇的站点上找出了 40 多个失效内链,其中一半是标签页被删导致的。
CDN 或反向代理引入的。比如 CDN 上配了图片处理规则,把 /img/x.jpg 改写成 /img/x.jpg@300w 但源站不认这个后缀。这种要看日志里 404 的 referer 是不是自己的域名,且 URL 有明显规律后缀。
第四步:死链修复的验证闭环
修完不是就完了,必须有验证。三类验证缺一不可:
验证重定向本身正确。用 curl -I 检查状态码和 Location 头,注意要跟到最终页,因为可能有重定向链:
curl -sIL "https://你的域名/old-post-123.html" | grep -E "^(HTTP|location)"期望看到一次 301 然后 200。如果看到 301 → 301 → 301 → 200,那就是重定向链,要把它压平——每多一跳,爬虫的抓取预算就多消耗一点,而且超过 5 跳浏览器会直接报错。
验证没有再产出新 404。修完第二天再看日志里同一个 URL 的请求状态。如果同一个 UA 还在请求旧的 404,说明某个地方还在链接它。
验证抓取预算的变化。这是最有说服力的一项。在 Google Search Console 的"抓取统计信息"(Crawl Stats)里看两个曲线:404 响应占比应该下降,200 响应数量应该上升。如果 404 降了但 200 没升,说明预算被别的东西吃掉了,继续找。
进阶:给死链做优先级排序
站点大了死链列表会很长,不可能全修。用下面的权重排序,从高到低处理:
一、有外部反链指向的 404。这类最优先,因为外部站点给你的权重正在落空。找出它们的方法是看日志里 referer 不是自己域名却返回 404 的请求,或者用 Search Console 的链接报告对照。
二、站内被多次引用的 404。用日志统计每个 404 URL 的请求次数,请求多的先修。
三、URL 结构上明显是旧文章、有可对应新文章的 404。这类做 301 收益直接。
四、纯扫描器产生的 404。不修,正确的做法是让它们返回 404 或者干脆用 Nginx 直接 drop 掉连接,减少日志噪音。
别忘了一个反向操作:主动清理被索引的垃圾
和死链相关但方向相反的一个问题,是已被索引但已经没价值的 URL。典型场景:早期做过标签云,生成了几百个只有一篇文章的标签页,全被收录了。这些页面内容稀薄、互相重复,会拉低整站的质量评估。
处理办法是给这些 URL 加 robots.txt 的 Disallow 加上页面上的 <meta name="robots" content="noindex">,两者要配合使用。只 Disallow 不行——被屏蔽抓取后爬虫无法看到 noindex,已经索引的页面会一直留在索引里,这是最常见的索引清理失败原因。正确的顺序是:先加 noindex 允许抓取,等页面从索引里消失后,再加 Disallow 避免无谓抓取。
把这件事变成常规工作
死链排查适合做成每月一次的例行任务,而不是出问题才想起来。建立一个简单的流程:每月 1 号跑日志分析脚本,输出"爬虫 404 TOP 30"和"站内失效内链清单",花一小时处理掉前十条,记录在案。坚持半年你会看到两个明确的变化:抓取统计里的 404 占比明显下降,新文章的收录速度变快。
SEO 里所有"见效慢"的困惑,归根结底往往是这类基础工作没做。内容写得再好,如果爬虫每次来都把配额花在追几百个死链上,你的新文章就只能排队。把这些噪音清掉,是给好内容让路,也是投入产出比最确定的一笔优化。