多数网站上,站内搜索结果页是低质量 URL 泄漏到 Google 的最大来源。它们动态生成、数量无限、和首页高度近似、更新速度比爬虫还快。Google 自己的指南也明确说过:默认情况下,站内搜索结果不该进索引。本文讲清这条规则、两个例外,以及如何干净落地。
问题背景
站内搜索把用户输入直接拼到 URL 上:/search?q=react+hooks、/search?q=react%20hooks、/search?q=foo+bar+baz+qux。每个不同查询都是新 URL。爬虫只要碰到一个小站,就能从内链、sitemap、外部 referrer 发现上千条。绝大多数内容很薄(一组标题列表),互相重复(同一查询不同写法),或者夹带垃圾查询。从 2007 年起 Google 就建议站长别让这些进索引,建议至今没变。
判断标准
- Search Console Pages 报告里
/search?q=...大量出现在「Crawled — currently not indexed」或「Duplicate, Google chose different canonical」。 site:yoursite.com inurl:search返回几百条你没打算发布的页面。- 有 spammer 拿垃圾查询去 ping 你的搜索接口,那些 URL 被收录了。
- sitemap 里意外包含
?q=URL,因为 URL 发现脚本爬了整站。
快速结论
默认:所有站内搜索结果页加 noindex。在模板里加 meta robots noindex,让 Google 自由抓取,看到指令再下架。不要在 robots.txt 里 Disallow——会让 Google 看不到 noindex,最后变成「只有 URL 没描述」的列表。两个例外见下。
两个例外
确实有两种情况,让搜索页进索引反而能赚流量。
例外 1:精选 landing 页。 如果你能预生成一组高价值查询作为真正的页面——/search/react-hooks、/search/python-async——那已经不是搜索结果,是有独立标题、描述、编辑过文案的 landing 页。当作完整文章处理。URL 看起来像搜索,内容是精选的。
例外 2:类目过滤式查询。 如果你的「搜索」其实是稳定商品库的过滤组合(/search?category=running-shoes&size=10),并且这种组合有真实搜索需求,可以让它进索引。但只让符合真实搜索意图的组合进,不是所有过滤组合都进。
其余情况:noindex。
正确加 noindex
<!-- 搜索模板里,针对真实查询页面加 -->
<meta name="robots" content="noindex, follow">
<!-- 或用 HTTP header(非 HTML 响应更干净) -->
X-Robots-Tag: noindex, follow
确保指令在任何重定向或 canonical 之前生效。爬虫抓到页面、看到 noindex、未来 1-3 周内逐步下架。保留 follow,结果页里指向真实文章的链接还能传递权重。
如果已经有上千个搜索 URL 被收录了,清理流程:
- 模板里加上
noindex。 - 找一个代表 URL,在 URL Inspection 里 Request indexing,Google 重新抓取后会下架。
- 接下来一个月观察 Pages 报告变小。
- 清理完成后,可以再给 robots.txt 加
Disallow: /search?节省抓取预算——但必须等 noindex 生效之后。
sitemap 和内链清理
页面上的 noindex 是策略层。sitemap 和内链是发现层。这两边一直指向搜索 URL,爬虫就一直在抓——就算最终不收录,抓取预算还是被浪费。
- 审 sitemap 生成器。如果它靠遍历页面找链接,就会把搜索框里的示例查询作为
?q=URL 收进 sitemap。构建阶段过滤掉这种模式。 - 减少模板里指向搜索的链接。常驻搜索框 submit 到
/search?q=没问题;底部硬编码 10 条「热门搜索」URL 就不行。 - 清理完之后,每周用
site:yoursite.com inurl:search跑一次,连续四周看收录数下降。如果数据停在某个值,找还在引用的链接删掉。
防垃圾查询注入
如果搜索接口把用户输入直接回显进页面 title 或 H1,你就免费送了一个 SEO 注入向量。spammer 用他们的目标关键词(俄文、日文、医药词常见)ping 你的搜索,结果 URL 就是你域名上一个薄弱页,他们要的关键词正好在 title 里——这正是他们想被收录的产物。
两道便宜的防御。第一,渲染前对用户查询做转义和截断——永远别让原始文本进 <title> 或 H1。第二,就算模板上挂了 noindex,也要在 CDN 层给这个接口加 rate limit。一个 IP 一小时打 /search?q= 500 次不是真人,直接 429 把这种 URL 抓取链断掉。
容易踩的坑
- 没先加
noindex就给 robots.txt 加Disallow: /search?。Google 抓不到页面、看不到noindex,URL 留在索引里、只剩裸 URL。 - 首页、header、footer 大量挂内链指向站内搜索。每条链接都是抓取邀请。加了
noindex也要减少内链数量。 - sitemap 包含
?q=URL,因为爬虫生成器一并收了。sitemap 构建阶段过滤掉。 - 忘了站内搜索 referrer 也会出现在 Search Console performance 报告里——那些是站内搜索,不是 Google 上的搜索。
- 让用户输入原样回显在页面标题里(
Search results for "spam-phrase-here")。spammer 用这个做 SEO 注入。
FAQ
- 该
noindex还是canonical?:noindex。canonical 适用于「这是另一个 URL 的相同内容」。搜索结果不是某个主页面的副本,是不该存在的薄弱页面。 - 搜索结果的分页呢?: 同一规则。每页都
noindex。分页本身也是噪音。 - 我的搜索是 Algolia / Meilisearch / 纯前端 JS 的,要管吗?: 只要用户搜索时 URL 会变(
?q=),Google 就会看到 URL 并尝试抓取。如果完全前端、URL 不变,就没东西要 noindex。 - noindex 搜索页会不会伤 SEO?: 不会。这些页面本来就排不到什么有竞争力的关键词。清掉提升的是抓取效率和整站平均质量。
- 能不能只让部分搜索页进索引?: 可以,看「精选 landing 页」那个例外。但严格说那已经不算「站内搜索」,是 URL 长得像搜索的内容页。
- 电商站的 facet / filter URL 怎么办?: 一样的逻辑。默认 noindex。白名单挑一小批高流量组合,做成有人写过文案的真实页面。
- Bing 行为一致吗?: Bing 遵循同样的
noindex和robots.txt语义。主流爬虫行为一致。