本文约 3,196 字,预计阅读 8 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:索引量里混进上千个空搜索页
排查收录质量时经常能看到这种 URL:/?s=插件、/?s=wordpress&submit=搜索、/?cat=3&order=desc&page=2。它们数量庞大、标题千篇一律是「搜索结果:xxx」、正文要么是空结果提示要么是和分类页高度重复的内容。这类页面不会带来流量,却实实在在消耗抓取配额,还会拉低站点整体的内容质量评估。更麻烦的是,百度没有提供类似「URL 参数处理」的后台开关,缺少一键配置的地方,只能靠 robots、noindex、canonical 三者配合,把这套规则自己搭起来。
原理分析:三类参数 URL 的不同处理方式
参数 URL 不能一律屏蔽。按价值分成三类:无价值型(站内搜索结果、排序筛选组合、追踪参数),目标是让百度别抓;有差异但重复型(分页、排序),目标是抓但要指回规范版本;有价值型(筛选后确实有独立内容的组合,如品牌+品类的聚合页),目标是可抓可收录,但要控制数量并写好标题与描述。搞混这三类,要么把有价值的页面屏蔽掉,要么放任垃圾页占满索引。
| 类型 | 例子 | robots | meta | canonical |
|---|---|---|---|---|
| 站内搜索结果 | /?s=关键词 |
Disallow | noindex,follow | 无 |
| 纯排序/追踪参数 | ?utm_source= |
不屏蔽 | 无需 | 指向无参数版本 |
| 分页 | /page/2/ |
不屏蔽 | index | 自身 |
| 有价值的筛选页 | ?brand=a&cat=b |
不屏蔽 | index | 自身 |
先说清一个事实:被 robots.txt 屏蔽的 URL,百度无法读取页面上的 noindex 指令,所以「既 Disallow 又 noindex」是自相矛盾的——页面可能因为外链被收录但看不到 noindex,只显示一条「由于该站的 robots.txt 无法抓取」的摘要。正确做法是二选一:要彻底不收录就只用 noindex(并允许抓取),或者只想省抓取配额就用 Disallow。想两者兼得,应先 Disallow 一段时间让已有索引掉出,再放开抓取并加 noindex,顺序不能反。
保姆级实操
步骤 1:摸清站内到底产生了多少参数 URL。 从资源平台的索引量报告与日志里导出 URL 列表,按参数名聚合:
grep -o 'GET [^ ]*' /var/log/nginx/access.log \
| grep '?' \
| sed 's/.*?//' \
| tr '&' '\n' \
| cut -d= -f1 \
| sort | uniq -c | sort -rn | head -20
步骤 2:在 WordPress 里动态生成 robots 规则。 与其手写一个 robots.txt 文件,不如用 robots_txt 过滤器,这样换主题、换域名都不会失效:
add_filter( 'robots_txt', function ( $output, $public ) {
if ( '0' === (string) $public ) {
return $output;
}
$lines = [
'User-agent: *',
'Disallow: /wp-admin/',
'Allow: /wp-admin/admin-ajax.php',
'Disallow: /search',
'Disallow: /*?s=',
'Disallow: /*?*s=',
'Disallow: /*?*submit=',
'Disallow: /*?*orderby=',
'Disallow: /*?*filter=',
'',
'Sitemap: ' . home_url( '/sitemap_index.xml' ),
'',
];
return implode( PHP_EOL, $lines );
}, 10, 2 );
步骤 3:给搜索结果页输出 noindex。 用 wp_head 钩子在搜索页插入 robots 元标签,注意保留 follow,让百度还能顺着页面上的链接发现其他内容:
add_action( 'wp_head', function () {
if ( is_search() ) {
echo '<meta name="robots" content="noindex,follow" />' . "\n";
}
}, 1 );
步骤 4:空结果页直接返回 404。 搜索无结果时返回 200 会让百度认为这是一个「正常但内容为空」的页面,属于典型的低质页。改成 404 更干净:
add_action( 'template_redirect', function () {
if ( is_search() && ! have_posts() ) {
global $wp_query;
status_header( 404 );
$wp_query->set_404();
nocache_headers();
}
}, 20 );
步骤 5:确认 sitemap 里不含参数 URL。 Yoast SEO、Rank Math 默认不会把搜索页放进 sitemap,但自定义文章类型与聚合页可能被插件加进去,需要逐个打开核对。?s= 这种形式一旦进了 sitemap,等于主动邀请百度来抓。
步骤 6:清理已有索引。 对已经被收录的搜索结果 URL,整理成 txt 提交到资源平台的「死链提交」,比单纯等它自然掉出要快得多。
常见踩坑
- 同时用
Disallow和noindex,页面因外链仍被收录,摘要显示「无法抓取」,反而更尴尬。 - 案例: 某站为了省事,在 robots 里写了
Disallow: /*?*,把带?p=123之类的早期固定链接一并屏蔽,导致几百篇历史文章从索引里消失,站点流量一个月内掉了 40%,加回Allow: /*?p=后才缓慢恢复。 noindex写在wp_footer里,主题某些模板没有调用wp_footer,指令根本没输出。- 用 JS 动态插入 noindex 标签,源码里没有,等于没写。
- 搜索页加了 noindex,但搜索表单用的是 POST 方法,结果页 URL 始终是
/,导致首页被误判。 - 改完 robots 立即生效期望太强,百度通常要一到两周才更新抓取规则。
- 屏蔽了参数页却没处理内链,站内依然有大量带参数的链接指向它们,百度顺着链接还是会来。
总结
判断参数 URL 该不该留,看它能不能独立回答一个用户的搜索需求。能回答的(有价值的筛选聚合页)就保留并写好标题;不能的(搜索结果、无差异排序)就屏蔽或加 noindex。行动清单:按参数名统计现有 URL → robots 用过滤器动态生成 → 搜索页 noindex,follow → 空结果返回 404 → 核对 sitemap → 已被收录的走死链提交。追踪参数的处理原则略有不同,见 UTM 参数对收录的干扰;整体收录质量的排查思路见 百度收录下降排查流程。
