一句话:robots.txt 里的 Disallow 阻止爬虫取这张页面,noindex 告诉它不要保留这张页面——而因为被 Disallow 的页面根本不会被取,它上面的 noindex 也就永远不会被读到,这正是陷阱所在。
这个陷阱,说精确一点
你想把某个目录从索引里去掉。于是在 robots.txt 里加了 Disallow: /internal/。爬虫不再取这些页面——因此也永远看不到你同时加上的 noindex。已经进了索引的页面留在那里,有时无限期地留着,有时还因为爬虫不被允许再看而显示为没有描述。
要把页面从索引里移除,就放行抓取并输出noindex。要把爬虫挡在一个它本来也不会收录的目录之外,用Disallow。对同一个 URL 两件事都做,达到的是你想要的反面。
哪种情况用哪个机制
| 目标 | 机制 |
|---|---|
| 把一张 HTML 页面从索引里移除 | <meta name="robots" content="noindex">,且放行抓取 |
| 移除 PDF、图片或 API 响应 | X-Robots-Tag: noindex 响应头——它们没有 head 可以放 meta 标签 |
| 把爬虫完全挡在后台路径之外 | Disallow,并接受它不会把已经在索引里的东西移除 |
| 把整个子域挡在外面 | 该子域自己的 robots.txt 写 Disallow: /,外加应用层的 noindex |
没人检查的那个子域
robots.txt 是按主机生效的。你营销站的那份对你的应用、文档站、预发环境或 CDN 主机只字未提。每一个都需要自己的一份,而常见故障是:应用子域压根没有 robots.txt——请求它返回的是应用自己的 404 页面,那不是 robots 文件,于是这个子域完全敞开。
我们在自己的产品子域上就撞到这一条:没有 robots.txt,而登录页已经开始拿到曝光了。产品后台没有任何理由出现在搜索结果里,而且它会稀释你真正在经营的那个域名的信号。
有意为之的双保险
对于一个永远不该被收录的界面,两件事都做:用 Disallow: / 的 robots.txt 阻止抓取,再用应用层的 noindex 覆盖「被别处链接后仍然被取走」的情况。两者覆盖不同的故障模式,而这是唯一一处「两件事都做」是正确而非矛盾的场景——因为这里你不需要「从索引移除」,你需要的是「一开始就不要进索引」。
按响应验证,不按配置验证
请求这个 URL,读真实的响应头和真实的 HTML。框架的 metadata API、CDN 规则和源站配置各自都可能覆盖对方,而唯一能盖棺定论的,是爬虫实际收到的那个响应。