robots.txt 写得好不好,决定你的图片能不能被搜到
大多数站长对 robots.txt 的态度是「建站时随手写两行,之后再也不看」。结果是:要么写得太宽松,让爬虫把后台、搜索页、参数页全爬了一遍,浪费抓取预算还制造一堆重复内容;要么写得太狠,一不小心把 CSS、JS、图片全 Disallow 了,导致 Google 渲染页面时看到的是白板,直接影响排名。
robots.txt 是一个「不写错比写得多更重要」的文件。本文不讲基础语法(那部分一页纸就够),而是聚焦几个真实踩坑场景:为什么你 Disallow 了还是被收录、CSS/JS 该不该屏蔽、通配符和 $ 的边界陷阱、以及「我需要的是 noindex 而不是 robots.txt」这个最常见的概念混淆。
先分清:robots.txt 是「抓取」控制,不是「收录」控制
这是最核心、也最常被误解的一点:
- robots.txt 控制爬虫能不能来抓(crawl)。它不保证页面不进索引。
- meta robots / X-Robots-Tag 控制页面能不能被收录(index)。
关键坑在于:如果一个 URL 被 robots.txt 屏蔽了,爬虫就抓不到页面内容,也就看不到页面里的 noindex 标签。 于是 Google 可能仅凭外链锚文本就把这个 URL「无内容收录」进索引(显示为「已发现 - 目前未收录」或直接以 URL 形式出现)。所以:
想彻底从索引里移除一个页面 → 用 noindex,不要用 robots.txt 屏蔽。 只有两者都不想让爬虫碰(比如后台、购物车、无限参数页)时才用 robots.txt。
正确的组合策略
# 想让某个页面彻底消失
# 1) 让页面返回 HTTP 200,并且在 head 里放:
<meta name="robots" content="noindex, follow">
# 2) robots.txt 里【不要】Disallow 这个路径
# 3) 等 Google 重新抓取后,noindex 生效,页面退出索引
# 4) 确认退出后再考虑要不要叠加 robots.txt 屏蔽顺序不能反。先 robots.txt 屏蔽再放 noindex,是彻底无效的操作,因为爬虫进不来、看不到 noindex。很多人死循环在这里。
CSS 和 JS 到底该不该屏蔽
老教程里经常写:
# 过时且有害的写法
User-agent: *
Disallow: /css/
Disallow: /js/
这个写法在今天是有害的。Google 使用移动优先索引,并且会渲染页面(渲染引擎执行 JS、加载 CSS)来判断页面质量、判断移动友好性、判断首屏内容。如果你屏蔽了 CSS/JS:
- Google 看到的是「无样式、无 JS 效果」的降级页面,可能判为「内容质量低」或「移动端不可用」。
- 大量用 JS 渲染内容的站(React/Vue SPA、按需加载的评论、懒加载正文)会直接导致内容抓不到。
- Search Console 的「网址检查 → 查看测试的页面 → 屏幕截图」会显示空白或残缺,一眼就能看出问题。
正确做法:不要屏蔽 CSS/JS 目录。如果你担心被爬取带宽,用限速或 CDN 缓存,而不是屏蔽。Google 官方文档明确建议让 Googlebot 能抓取渲染所需资源。
例外:这些资源可以屏蔽
- 字体大文件(
/fonts/)如果同时被其他方式引用,一般不必屏蔽,但可考虑。 - 纯装饰性、渲染无关的静态资源目录。
- 但如果是首屏渲染必需的资源,一律不屏蔽。
通配符 * 与结尾 $ 的边界陷阱
robots.txt 只支持两种特殊字符:*(任意字符序列)和 $(结尾锚定)。不支持正则、不支持 ? 转义、不支持 !。常见的错法:
# ❌ 错误:以为能匹配「路径结尾是 ?」
Disallow: /*?
# 实际含义:屏蔽所有「路径里含 ?」的 URL —— 这会把带参数的正常页面也屏蔽掉
# 如果站上很多内容靠 ?id= 分发(如 /article?id=123),这会屏蔽掉整站内容
# ✅ 只屏蔽搜索结果页这类参数页,用更精确的路径前缀
Disallow: /search
Disallow: /*?s= # 匹配 ?s= 关键词搜索
Disallow: /*&print= # 匹配打印参数(注意 & 在 robots.txt 里就是普通字符)
$ 的用法:只有放在模式末尾才表示「URL 到此结束」。例如:
# 只屏蔽 /admin 本身,不屏蔽 /admin/xxx
Disallow: /admin$
# 对比:不带 $,屏蔽 /admin 及 /admin/ 下所有子路径
Disallow: /admin
这个区别在你想「保留某个目录但屏蔽它的入口页」时会用到。反之,很多人以为 Disallow: /admin$ 能屏蔽整个后台,结果后台子页照样被爬——$ 是精确结尾,不是目录通配。
大小写与 URL 规范
robots.txt 的路径匹配是区分大小写的,且基于 URL 的路径部分(不含域名),参数部分是否包含在匹配范围内取决于实现。所以 /Search 和 /search 是两条规则。写之前先确认你的实际 URL 大小写,别想当然。
多 User-agent 段的合并规则
当 robots.txt 里有多个 User-agent 段时,规则是这样的:
User-agent: *
Disallow: /tmp/
User-agent: Googlebot
Disallow: /nogoogle/
User-agent: BadBot
Disallow: /
一个名为 Googlebot 的爬虫,会合并所有与它匹配的段(Googlebot 段 + * 段),而不是只取最匹配的那一段。上例中 Googlebot 的最终规则是「Disallow /tmp/ 且 Disallow /nogoogle/」。很多人以为写了 Googlebot 段就会覆盖 * 段,这是错的。
想单独限制某个爬虫而不继承 * 的规则 → 做不到,除非你在 * 段里就不写那些规则。所以设计时要把「全局规则」和「特定爬虫规则」当成叠加关系来思考。
匹配优先级:最长匹配 + Allow 优先
当 Allow 和 Disallow 同时能匹配一条 URL 时,按两条规则裁决:
- 比较匹配模式的长度,更长的(更具体的)获胜。
- 长度相同时,Allow 优先于 Disallow。
User-agent: *
Disallow: /private/
Allow: /private/public.html
# /private/public.html 会被允许(Allow 规则更长)
# /private/other.html 会被禁止
注意 Google 的匹配长度计算是基于模式字符串本身(含 *、$),不是匹配到的 URL 长度。别用「更长的 URL」这种直觉去推断。
动态 robots.txt 与多环境
如果你的站分「开发/测试/生产」,且测试环境不希望被收录,不要简单复制一份 Disallow: / 的 robots.txt 就完事——因为一旦测试环境被某个外链指向、或有人从测试环境复制内容,还是可能出问题。更稳的做法是测试环境整体加 HTTP Basic 认证(返回 401,爬虫直接放弃),robots.txt 只是辅助。
对于需要动态生成的 robots.txt(比如按环境注入 sitemap URL),注意两点:
- 返回
Content-Type: text/plain,不要是text/html。 - 返回 200。如果是 404 或 5xx,Google 会短暂视为「允许全部」,但长期 5xx 会导致抓取降级。
# 方案一:直接返回静态字符串(每条规则一行,真实换行)
location = /robots.txt {
default_type text/plain;
return 200 "User-agent: *
Disallow: /admin
Disallow: /search
Allow: /
Sitemap: https://你的域名/sitemap.xml
";
}
# 方案二(更推荐):用一个真实文件承载,Nginx 只负责返回
# 写 /var/www/robots.txt,然后:
location = /robots.txt {
root /var/www;
default_type text/plain;
try_files /robots.txt =404;
}常见错误清单与真实影响
把上面这些规则落到实操上,下面几种写法是踩坑重灾区,逐条对照检查:
| 错误写法 | 你以为的效果 | 实际后果 |
|---|---|---|
Disallow: /*? | 只屏蔽搜索页 | 屏蔽所有带参 URL,动态内容全被挡 |
Disallow: /css/ | 省点抓取预算 | 页面渲染降级,判为质量低 |
Disallow: /admin$ | 屏蔽整个后台 | 只屏蔽 /admin 一个页面,子路径照样抓 |
Disallow: / 后想删索引 | 页面从搜索消失 | 爬虫看不到 noindex,仍可能无内容收录 |
Disallow: /sitemap.xml | 隐藏站点地图 | 收录入口被切断,新内容长期不收录 |
表格里第三条特别隐蔽:很多人以为 /admin$ 能保护后台,其实后台的登录页、列表页、编辑页全在子路径下,一条都没被挡。想屏蔽整个后台应该用 Disallow: /admin/(带尾部斜杠,匹配整个目录),而不是加 $。
robots.txt 不能替代的其他措施
还有一类误解是「robots.txt 能防一切」。它做不到,也不该被这样用:
- 防不住恶意爬虫:君子协定,只对守规矩的搜索引擎有效。写爬虫的想绕过,改个 User-agent 就来。真要防护得靠限流、WAF、fail2ban。
- 敏感信息保护:有人把后台、配置文件路径写进
Disallow,等于主动告诉全世界「这里有东西,快来试」。敏感路径应该靠鉴权保护,不是靠 robots.txt。 - 即时生效:改了 robots.txt 不会立刻生效。Google 会缓存它,最长可能数天。紧急情况(比如发现误屏蔽)要用 Googlebot 的抓取工具强制刷新缓存,或临时返回 404。
上线前的自查清单
- 有没有误伤 CSS/JS/图片? 全文搜
Disallow,确认没有/css、/js、.css、.js、.jpg之类。 - 有没有把 sitemap 自己屏蔽了?
Disallow: /或Disallow: /sitemap会让 sitemap.xml 无法被抓,收录直接停摆。 - 有没有
Disallow: /*?这种屠杀式规则? 会连带屏蔽所有带参页面。 - 语法是否合法? 用 Google Search Console 的 robots.txt 测试工具,或
curl -s https://你的域名/robots.txt肉眼过一遍。 - 是否把「想删索引」和「不想被抓」搞混了? 要删索引用 noindex,不用 robots.txt。
- User-agent 名称拼写对不对?
Googlebot不是googlebot也不是Google-bot;拼错的段会落到*里,规则形同撤销。
小结
robots.txt 的价值不在于「写得多」,而在于不写错。记住三条底线:想要页面彻底消失用 noindex 不用 Disallow;永远不要屏蔽 CSS/JS;通配符 * 和结尾 $ 的语义要精确理解,别用 /*? 这种误伤全站的规则。 每次改完 robots.txt,都去 Search Console 里用测试工具跑一遍,改错这个文件造成的收录损失,往往比你想的严重得多。