搜索全站
插件 13 分钟阅读

WordPress 站点地图冲突排查:插件与主题自带 Sitemap 重复的识别与统一

同时存在三份 sitemap.xml,搜索引擎该听谁的?本文讲清 WordPress 核心 sitemap、Yoast/Rank Math 插件 sitemap、主题自带 sitemap 三者的识别方法、禁用方式与 robots.txt 统一声明的完整流程。

U
UFO_PF 2022-07-15 · 阅读 13 分钟
Wo 插件
阅读提示
本文约 4,813 字,预计阅读 13 分钟。文中命令与配置均经过实测,可直接参考执行。

引言:site.com/sitemap_index.xml 的背后,藏着三套互不相干的规则

一个典型的 WordPress 站点运行两年后,很可能同时存在以下几份站点地图:

  • WordPress 核心自带:wp-sitemap.xml(WP 5.5+ 引入),索引里包含 posts、pages、taxonomies、users
  • SEO 插件的:Yoast 是 sitemap_index.xml,Rank Math 也是 sitemap_index.xml(两者文件名相同会直接冲突)
  • 主题自带的:部分商务主题(比如某些 Themeforest 主题)自己注册了 /sitemap.xml rewrite
  • 缓存/ era/hosting 面板自带的:有些主机控制面板会额外生成静态 sitemap

这不是洁癖问题。多份 sitemap 会带来三个实打实的后果:第一,GSC 里”已发现的网址”和”索引”迟迟不上涨——因为搜索引擎要在多份地图里去重,且其中可能有 404 的条目;第二,权重 signals 分散,同一 URL 在不同 sitemap 里的 lastmod 不一致会让引擎困惑;第三,GSC 提交数和实际抓取量不匹配,排查起来极其费时。

本文讲怎么稳扎稳打地把多份回归到一份。

原理分析:区分三层的”Sitemap”概念

层级 位置 谁生成 如何关闭
核心 XML 站点地图 /wp-sitemap.xml WP 核心 WP_Sitemaps 类 remove_action/wp_sitemaps_enabled 过滤器
插件 sitemap /sitemap_index.xml Yoast / Rank Math / SEOPress / All in One SEO 插件后台开关
robots.txt 里的声明 /robots.txt 的 Sitemap: 行 由上述任一 réaliser 自动添加 由谁生成就改谁
主题/自定义 各种 URL 主题的 rewrite 规则 主题选项或 remove_rewrite

三条必须记住的技术事实:

第一,核心 sitemap 用 wp_sitemaps_get_server 注册 provider。 想精确控制某一类内容是否进入核心地图,用 wp_sitemaps_add_provider / wp_sitemaps_enabled 过滤器。

第二,robots.txt 是虚拟的。 WordPress 通过 do_robots() 动态输出 robots.txt,因此服务器上不会有 robots.txt 文件。如果根目录存在真实 robots.txt 文件,它会优先于 WordPress 生成的那份,导致你在后台改了 sitemap 声明却完全不生效——这是非常高频的坑。

第三,Sitemap: 指令建议写成绝对 URL 且放在 robots.txt 末尾。 另外注意:Google 支持 robots.txt 里声明,Bing/百度同样支持;但百度站长平台更推荐直接在平台后台提交。

保姆级实操

步骤 1:先清点所有 sitemap

for u in wp-sitemap.xml sitemap_index.xml sitemap.xml xmlsitemap.xml post-sitemap.xml; do
  code=$(curl -s -o /dev/null -w "%{http_code}" "https://example.com/$u")
  size=$(curl -s "https://example.com/$u" | wc -c)
  echo "$u -> HTTP $code, ${size} bytes"
done

同时看 robots.txt:

curl -s https://example.com/robots.txt

把输出里的每一行 Sitemap: 记下来,它就是你接下来要统一的目标。

步骤 2:关闭 WordPress 核心自带的 wp-sitemap.xml

两种取舍:

// A:彻底关闭核心 sitemap(装了 Yoast/Rank Math 时推荐)
add_filter( 'wp_sitemaps_enabled', '__return_false' );

// B:保留核心地图,但剔除 users 归档(避免泄露作者用户名)
add_filter( 'wp_sitemaps_add_provider', function( $provider, $name ) {
    if ( 'users' === $name ) {
        return false;
    }
    return $provider;
}, 10, 2 );

步骤 3:处理 Yoast / Rank Math 的同名冲突

Yoast 与 Rank Math 都占用 /sitemap_index.xml。同时启用会以先注册 rewrite 规则者胜出,另一方的 URL 会 404。必须二选一:

  • 保留 Yoast:「Yoast SEO → Settings → Features」→ 关闭 Crawl optimization 里的 “Remove core search”? 不需,重点是「Rank Math → Sitemap Settings → 关闭」。
  • 保留 Rank Math:「Yoast SEO → 功能 → XML 站点地图」关闭。

用代码核验是否已关闭:

wp option get rewrite_rules | grep -o 'sitemap' | head

步骤 4:清理残留的 rewrite 规则

插件卸载后旧的 rewrite 规则会留在 wp_options 的 rewrite_rules 里,导致 URL 仍然 200 但内容为空:

# 刷新 rewrite 规则(等价于后台「设置→固定链接→保存」)
wp rewrite flush --hard
wp cache flush

步骤 5:统一 robots.txt 里的 Sitemap 声明

不要同时依赖多个插件去写这行,容易互相覆盖。直接在主题的 robots_txt 过滤器里一次性定义:

add_filter( 'robots_txt', function( $output, $public ) {
    if ( '0' === (string) $public ) {
        return $output; // 站点被设为不公开时保持原样
    }
    $lines   = explode( "\n", $output );
    $lines   = array_filter( $lines, function( $line ) {
        return stripos( $line, 'Sitemap:' ) === false; // 先移除别人加的
    } );
    $lines[] = 'Sitemap: ' . home_url( '/sitemap_index.xml' );
    return implode( "\n", $lines ) . "\n";
}, 99, 2 );

优先级设 99 保证最后一个执行,把你自己的声明写进去。

步骤 6:处理”真实 robots.txt 文件抢跑”

# 检查站点根目录是否有物理 robots.txt(有则 WordPress 的钩子无效)
ls -la /var/www/example.com/robots.txt

如果存在需要处理:要么删掉物理文件让 WordPress 接管,要么接受物理文件为唯一来源并在里面手动写好 Sitemap: 行(意思是后续自动化失效,每次改 sitemap 都得手动改文件)。推荐前者。

步骤 7:在 GSC 与百度平台重新提交

清理完毕后,在 Google Search Console 的「站点地图」里删除旧的、只提交唯一的 sitemap_index.xml;百度站长平台同样处理。

常见踩坑

  1. 站点设成了”建议搜索引擎不索引本站点”:「设置 → 阅读」的那个勾选会让 robots.txt 输出 Disallow: /。很多站长迁移后忘了取消。这是收录为零的第一大原因。
  2. HTTP/HTTPS 或 www 的 canonical 不一致:sitemap 里的 URL 是 http:// 而站点 canonical 是 https://,GSC 会报”sitemap 中的网址与站点不匹配”。确保 home_url() 返回的是最终形态(is_ssl() 感知)。
  3. 案例:某外贸站点运营三年,GSC 里 sitemap 一直显示”已发现 2,340 个网址,但最新读取一直失败”。排查发现:站点曾经装过一个 All in One SEO Pack 并卸载,但它写入根 robots.txt 的两行 Sitemap: 指向了早已失效的 sitemap_index.xml?ver=2 与一篇 404 的 post-sitemap.xml。更惨的是这份 robots.txt 是物理文件,其后所有插件在后台做的 sitemap 配置全部无效。清理物理文件 + wp rewrite flush + 重新提交之后,两周内新索引文章 +187 篇。教训:robots.txt 与 sitemap 这类”看不见的配置”要列入迁移/交接清单。
  4. wp_sitemaps_enabled 关不掉 Yoast:两者是独立系统,这个过滤器只管核心的 wp-sitemap.xml。
  5. CDN 缓存了旧的 robots.txt:robots.txt 也会被 CDN/APO 缓存,改完后记得 purge。
  6. 同一份 sitemap 出现 404 子项:trash 里的文章、被 noindex 的 URL 会被插件保留在 sitemap 中。Yoast 会自动排除 noindex 的条目,但有些主题地图不会。
  7. <lastmod> 每次构建都变:部分插件用 time() 而不是文章真实修改时间,导致搜索引擎认为全站都在更新,抓取预算被浪费。用 get_the_modified_date( 'c', $post ) 才是正确取值。
  8. Nginx 自身 rewrite 抢了 /sitemap.xml:有些一键安装包自带伪静态规则重写 sitemap 到某个静态文件。检查 Nginx conf 里 location = /sitemap.xml。

延伸阅读:XML Sitemap 拆分策略、robots.txt 配置详解

总结

统一 sitemap 只需要做对四件事:①清点(用上面的循环脚本扫所有常见路径 + 看 robots.txt);②二选一(Yoast 与 Rank Math 只能留一个,另一个的 sitemap 开关必须关);③关核心(wp_sitemaps_enabled 或至少剔除 users provider);④回 robots.txt 收拢为一行,并检查是否存在物理 robots.txt 文件抢跑。完成后在 GSC 重提、观察 1–2 周的”已发现网址”变化,这是唯一可靠的验收指标。

U
UFO_PF作者

专注 WordPress 生态的实战作者,内容以「可复制、可验证」为第一原则。

留下你的想法

邮箱地址不会被公开。带 * 的为必填项。