本文约 3,832 字,预计阅读 10 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:改版三个月,索引里还挂着一批 404 页面
站点改版、删除旧文章、更换图片路径之后,百度索引里的旧 URL 不会立刻消失。爬虫每次来访都会去抓这些已经不存在的地址,浪费抓取配额,用户点进去则直接看到 404。很多站长的处理方式是”等百度自己更新”,但这个过程可能持续数月。更麻烦的是,内部链接里也残留着指向已删除内容的链接——新文章里引用了一篇后来被删掉的教程,用户点了就是死链,而站长自己往往察觉不到。
原理分析:死链为什么需要主动提交
百度发现死链的路径有三条:爬虫抓到 404 → 一段时间后降低权重 → 从索引中移除。这条路径的问题在于周期长且不确定。主动提交死链的价值在于:
第一,加速索引清理。提交后百度会优先处理这批 URL,把它们从结果中撤下,避免用户点到死链影响体验。
第二,释放抓取配额。每个站点的抓取预算有限,爬虫反复抓 404 页面,意味着真正重要的新页面被抓取的机会减少。
第三,暴露内部管理问题。死链清单往往能反映出内容删除流程、URL 变更流程中的漏洞。
死链提交有两种方式:文件提交(列出具体的死链 URL 列表)和规则提交(用正则表达一类 URL)。前者适合数量明确的离散死链,后者适合批量路径变更(比如整个目录下线、URL 规则变化)。提交入口在百度搜索资源平台,路径大致为”数据提交 → 死链提交”(随平台改版入口名称可能微调,可在后台顶部搜索”死链”定位)。
保姆级实操
步骤1:先做站内死链扫描
用一段脚本遍历全部已发布内容里的内部链接,逐一发 HEAD 请求检查状态码:
// 一次性脚本:扫描正文内部链接并返回非 200 的清单(用完即删)
add_action( 'init', function() {
if ( ! current_user_can( 'manage_options' ) || ! isset( $_GET['scan_dead'] ) ) {
return;
}
$q = new WP_Query( array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
) );
$dead = array();
$home = home_url();
foreach ( $q->posts as $id ) {
$content = get_post_field( 'post_content', $id );
if ( ! preg_match_all( '/href="(' . preg_quote( $home, '/' ) . '[^"]+)"/i', $content, $m ) ) {
continue;
}
foreach ( array_unique( $m[1] ) as $url ) {
$res = wp_remote_head( $url, array( 'timeout' => 5 ) );
$code = is_wp_error( $res ) ? 0 : wp_remote_retrieve_response_code( $res );
if ( 200 !== $code ) {
$dead[] = get_the_title( $id ) . ' -> ' . $url . ' (' . $code . ')';
}
}
}
wp_die( '<pre>' . esc_html( implode( "\n", $dead ) ?: '未发现死链' ) . '</pre>' );
} );
步骤2:从数据库里排查已删除内容的残留引用
图片和附件被删除后,正文里的 URL 不会自动清理,可以用 SQL 快速定位:
-- 查找正文中指向已不存在附件的引用(示意:列出所有 wp-content/uploads 链接)
SELECT ID, post_title
FROM wp_posts
WHERE post_status = 'publish'
AND post_content LIKE '%/wp-content/uploads/%'
AND post_content REGEXP 'wp-content/uploads/20(2[0-9])/';
步骤3:结合服务器日志找高频 404
服务器访问日志里状态码为 404 的记录是最真实的死链来源。用命令行快速统计:
# 统计访问日志中出现次数最多的 404 URL(Nginx 默认日志格式)
awk '$9==404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -50
步骤4:生成死链 txt 文件
死链文件要求每行一个完整 URL,纯文本,放在站点根目录下可被访问的路径。可以用代码生成并写入文件:
// 一次性脚本:把死链清单写成 deadlinks.txt(用完即删,注意目录写权限)
add_action( 'init', function() {
if ( ! current_user_can( 'manage_options' ) || ! isset( $_GET['make_dead'] ) ) {
return;
}
$list = array(
home_url( '/old-post-1/' ),
home_url( '/old-post-2/' ),
home_url( '/wp-content/uploads/2023/01/old.png' ),
);
$file = ABSPATH . 'deadlinks.txt';
file_put_contents( $file, implode( "\n", $list ) . "\n" );
wp_die( '已生成:' . home_url( '/deadlinks.txt' ) . ',共 ' . count( $list ) . ' 条' );
} );
步骤5:确认死链真的返回 404
提交前必须验证这些 URL 返回的是 404(或 410),而不是 200。返回 200 的软 404 会被拒绝处理,判断方法见 404页面与状态码规范。
步骤6:在搜索资源平台提交文件
进入百度搜索资源平台,找到死链提交入口,填写死链文件的完整 URL(必须是可公网访问的 txt 地址),提交后等待处理。
步骤7:批量路径变更用规则提交
如果整个目录或 URL 规则变化,用正则规则提交更高效,例如把所有 /20xx/ 开头的旧路径一次性声明为死链。规则提交需要用平台支持的正则语法,提交前先在少量 URL 上验证匹配是否准确。
步骤8:修复内部死链
提交只是清理索引,站内正文里的死链仍需修复:删除链接、改为 301 目标页或替换为新 URL。
常见踩坑
- 提交返回 200 的软 404:百度会拒绝处理,必须先修状态码。
- 死链文件带 BOM 或有空行:可能导致解析失败,生成时用纯文本、UTF-8 无 BOM。
- 把临时故障当死链提交:服务器短暂异常导致的 404 提交后,页面恢复又需要重新提交恢复。
- 只提交不修内链:索引清了,但用户从站内文章点进去还是 404。
- 案例:某站点删除了 300 多篇旧文章但没做 301,两个月后搜索资源平台显示大量 404 抓取异常。站长直接从”抓取异常”列表导出 URL 生成死链文件提交,两周后这批 URL 基本从索引中消失;但站内还有 40 多篇文章的正文引用了这些地址,后来用 SQL 批量替换才彻底解决。
- 死链文件放错位置:放在需要登录才能访问的路径下,百度抓不到。
- 忽略 sitemap 里的残留:旧 URL 仍在 sitemap 中,一边提交死链一边又推送,信号自相矛盾。
总结
死链处理的完整闭环是:扫描(脚本 + 日志 + 平台抓取异常)→ 确认返回 404 → 生成 txt 文件 → 平台提交 → 修复站内引用 → 清理 sitemap。其中”修复站内引用”最容易被跳过,却是唯一能直接改善用户体验的一步。建议每季度做一次全站扫描,改版后必须立即做一次。如果死链是换域名或改路径导致的,应优先用 改版工具URL变更使用方法 做规则提交,而不是等到 404 之后再补交死链。
