本文约 4,848 字,预计阅读 13 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:sitemap 里 80% 是垃圾页
一个典型的 WordPress 站点,文章可能只有几百篇,但 sitemap 里躺着几千条 URL:标签归档、作者归档、附件页(每个上传的图片都有独立页面)、分页、评论分页。把这些一股脑提交给百度,等于告诉它”这些页面都很重要”。结果往往是抓取预算被稀释——百度抓了一堆标签页,真正的新文章反而排在队列后面。更合理的做法是给百度一份”精选目录”:只含文章页、页面、核心栏目页。本文给出三种实现路径,从零配置到纯代码。
原理分析:sitemap 应该只装”值得索引”的 URL
搜索引擎给每个站点分配的抓取资源(常说的抓取预算)是有限的,它会按 sitemap、外链、历史更新频率等因素排序抓取。sitemap 本质上是你在向百度”投票”:出现在里面的 URL 会被认为更重要。因此 sitemap 的编制原则是越少越好、越精越好——前提是每一条都值得收录。
判断哪些页面该进 sitemap,可以用三个问题筛:
| 页面类型 | 是否进 sitemap | 理由 |
|---|---|---|
| 文章/产品详情页 | 是 | 有独立内容价值 |
| 栏目/分类页 | 选择性进 | 有实质内容与描述时进 |
| 标签页 | 否 | 易产生大量同质页 |
| 附件页 | 否 | 内容极薄 |
| 搜索结果页 | 否 | 属低质,处理办法见用robots屏蔽低质量页面的正确方式 |
| 分页(page/2) | 否 | 内容与首页重复 |
WordPress 5.5 起自带 sitemap(/wp-sitemap.xml),它默认包含文章、分类、标签、作者。要精简它,不必装插件,用官方提供的过滤器即可;反过来,如果你用 Yoast SEO、Rank Math、All in One SEO 这类插件,它们各自的 sitemap 设置里也有排除项界面。
保姆级实操
方式一:用插件界面排除(零代码)
Yoast SEO:SEO → 常规 → 站点地图,可关闭”作者/媒体/格式”等类型的站点地图;具体某篇文章可在编辑页的 Yoast 面板设为 noindex,它会自动从 sitemap 移除。Rank Math:站点地图设置 → 常规,可勾选要包含的文章类型与分类法,并排除指定条目。这类界面操作的优点是可视化、可逆,缺点是无法做复杂条件(例如”排除 300 字以下的文章”)。
方式二:用 WordPress 原生钩子改写自带 sitemap
把下面代码放进子主题 functions.php。注意:wp_sitemaps_post_types、wp_sitemaps_taxonomies、wp_sitemaps_posts_query_args、wp_sitemaps_posts_entry 都是 WordPress 真实提供的过滤器,不需要装任何插件。
<?php
// 1) 只保留文章与页面两种内容类型
add_filter( 'wp_sitemaps_post_types', function ( $post_types ) {
unset( $post_types['attachment'] );
// 若有自定义类型 product,可保留:return array( 'post', 'page', 'product' );
return array_intersect_key( $post_types, array_flip( array( 'post', 'page' ) ) );
} );
// 2) 移除标签与作者归档
add_filter( 'wp_sitemaps_taxonomies', function ( $taxonomies ) {
unset( $taxonomies['post_tag'] );
return $taxonomies;
} );
// 作者归档需要额外处理:把查询参数改成查不到任何结果
add_filter( 'wp_sitemaps_users_query_args', function ( $args ) {
$args['include'] = array( 0 ); // 无匹配用户
return $args;
} );
// 3) 排除正文过短、或标记为 noindex 的文章
add_filter( 'wp_sitemaps_posts_query_args', function ( $args, $post_type ) {
if ( 'post' !== $post_type ) {
return $args;
}
$args['meta_query'] = array(
'relation' => 'AND',
array(
'key' => '_mimangfei_word_count',
'value' => 300,
'compare' => '>=',
'type' => 'NUMERIC',
),
);
$args['posts_per_page'] = 1000; // 单文件条目上限,默认 2000
return $args;
}, 10, 2 );
// 4) 给每条 URL 补上 changefreq / priority,并排除加密文章
add_filter( 'wp_sitemaps_posts_entry', function ( $entry, $post ) {
if ( ! empty( $post->post_password ) ) {
return array(); // 返回空数组即不输出该条
}
$entry['changefreq'] = 'weekly';
$entry['priority'] = 0.7;
return $entry;
}, 10, 2 );
// 5) 每个 sitemap 文件的最大条目数(默认 2000,改小可让百度更快读完)
add_filter( 'wp_sitemaps_max_urls', function () {
return 1000;
} );
方式三:生成独立的 baidu-sitemap.xml
如果不想动默认 sitemap,可以在站点根目录放一个由计划任务生成的静态文件,只在资源平台提交这个地址:
<?php
// 每小时生成一次 /baidu-sitemap.xml
add_action( 'init', function () {
if ( ! wp_next_scheduled( 'mmf_build_baidu_sitemap' ) ) {
wp_schedule_event( time(), 'hourly', 'mmf_build_baidu_sitemap' );
}
} );
add_action( 'mmf_build_baidu_sitemap', function () {
$q = new WP_Query( array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 2000,
'no_found_rows' => true,
'fields' => 'ids',
) );
$xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n"
. '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";
foreach ( $q->posts as $id ) {
$xml .= " <url>\n"
. ' <loc>' . esc_url( get_permalink( $id ) ) . "</loc>\n"
. ' <lastmod>' . get_post_modified_time( 'c', true, $id ) . "</lastmod>\n"
. ' <changefreq>weekly</changefreq>' . "\n"
. " </url>\n";
}
$xml .= '</urlset>';
file_put_contents( ABSPATH . 'baidu-sitemap.xml', $xml );
} );
验证:改完后 curl -s https://mimangfei.com/wp-sitemap.xml 看索引里是否只剩 posts 与 pages 两类子文件,再抓子文件确认条目数。
常见踩坑
- 改了代码但缓存插件还在输出旧 sitemap:需要清缓存,并把
wp-sitemap*.xml从缓存规则中排除。 wp_sitemaps_post_types返回空数组导致 404:至少保留一个类型,否则 sitemap 索引为空、百度抓取为 0 条。meta_query依赖的自定义字段不存在:没有_mimangfei_word_count的文章会被整体排除(因为不存在该 key 的记录不满足>=),上线前先给历史文章补字段或用 SQL 回填。- 把 noindex 的页面留在 sitemap:信号矛盾,百度会认为 sitemap 不可信。
- 案例:某站用插件生成 sitemap,默认把
attachment类型也纳入,2000 多条图片附件页被提交,百度抓取日志里附件页占了七成。关掉 attachment 后,文章页抓取量翻倍,两周内新增收录明显加快。 - 更新频率写成 hourly 却没有真更新:
changefreq只是建议值,乱写会让百度降低对该字段的信任。 - 计划任务没跑:
wp_schedule_event依赖 WP-Cron,站点流量低时可能延迟,可用系统 crontab 调wp cron event run兜底。
总结
判断标准:一份合格的百度 sitemap,条目数应接近你”希望被收录的页面数”,而不是”站点 URL 总数”。行动清单:列出全站 URL 类型 → 用三问筛法删掉标签/附件/搜索/分页 → 优先用插件界面,复杂条件再上钩子 → 改完清缓存并用 curl 验证 → 平台提交后看”有效条数”。关于 sitemap 本身的格式与提交入口,可回看百度sitemap提交的多种方式。
