
你是不是也遇到过这种情况某个时间点开始服务器日志里出现一种特征明显的UAUser-Agent请求间隔精确到秒访问路径顺序规整带宽和CPU占用直线上升。查了一圈发现不是什么攻击而是某个搜索引擎或数据采集工具的Web机器人Web Robot在抓取内容。这个时候大家想到的第一道防线十有八九是robots.txt。我这些年跟Web机器人和robots.txt协议打了无数次交道既做过站点方也写过爬虫去抓别人的公开数据。只要理解了这份纯文本文件背后的协议规则很多抓取异常、索引异常、带宽被占满的问题都能迅速定位。这篇文章想把这件事讲透机器人的工作机制、robots.txt的语法与匹配优先级、从零配置一份线上可用的robots.txt、配套的页面级管控手段以及我实际踩过的一些坑。站点运维、SEO人员、爬虫开发者和做流量分析的读者都可以参考。1. Web机器人到底在做什么先认清它们的真面目1.1 机器人的身份识别UA字符串与网络特征Web机器人本质上是一段程序按照预设规则自动发起HTTP请求、下载网页并提取内容不需要人工干预。大家最熟悉的类型是搜索引擎抓取机器人也就是俗称的蜘蛛Spider它们负责把页面抓回去建立索引。但机器人远不止搜索引擎在用SEO分析工具、价格监控平台、舆情监测系统、数据采集爬虫甚至一些恶意的内容搬运工具都是以机器人的形态在互联网上活动。识别机器人最直接的方法是看User-Agent请求头。规范的爬虫都会在UA里暴露自己的身份通常会带bot、spider、crawler这类关键词。举个例子形如MyCompanyBot/2.0 (https://yourdomain.com/bot-info)的UA一眼就知道它是谁家的机器人。也有一些爬虫会把UA伪装成普通浏览器这时要结合行为特征判断单IP短时间内高频请求、并发连接数高、访问的URL模式非常规律、缺失图片等静态资源请求、浏览器指纹不完整这些都是机器人的典型信号。从网络层面看机器人的IP段通常比较集中很多抓取工具会从固定的IDC网段发起请求。通过分析访问日志里的IP归属、请求时间分布、HTTP状态码占比可以建立一套简单的机器人识别规则。这也是我后面做访问日志监控时的基本功。1.2 为什么必须管理机器人收益与风险并不是所有Web机器人都是坏事。搜索引擎爬虫带来的自然流量价值巨大做公开资料归档的机构抓取也属于正常用途。问题出在“不加节制的抓取”上。我见过不少站点的服务器日志里单日被同一个机器人抓取上万次带宽被打满正常用户访问变卡数据库连接数耗尽严重的时候整站宕机。还有一些采集工具专门盯着后台地址、接口路径反复试探这类行为虽然不是传统意义上的安全攻击但会给运维带来大量额外工作。所以管理Web机器人的核心目标不是“一律屏蔽”而是分级对待。对合规、有用的机器人用robots.txt配置合理的抓取范围对来源可疑、负载异常的机器人用服务器层面的限流和封禁兜底。robots.txt是这套管理机制里最高层、最公开的声明它告诉所有遵守协议的机器人哪些路径你可以抓哪些路径请不要碰。需要注意的是robots.txt在协议上是一种“君子协定”。搜索引擎和正规爬虫会遵守但纯粹的恶意程序根本不会看。理解这一点你才不会把robots.txt当成安全工具——它的本职是流量治理和索引管理安全隔离还需要防火墙、WAF和访问控制去解决。2. robots.txt该怎么写基础语法与优先级一次讲透2.1 三个基础指令User-agent、Allow、Disallowrobots.txt的载体是网站根目录下的一个纯文本文件协商方式很简单爬虫抓取某站点之前先尝试请求https://yourdomain.com/robots.txt拿到这份文件之后再按文件里的规则决定抓取哪些URL。文件不在根目录、或者返回非200状态码规范上视为不限制抓取。文件主体由多个规则块组成每个规则块以User-agent开头后面跟一个或多个Allow和Disallow。User-agent指定规则适用的爬虫名*号表示匹配所有未明确指定的爬虫Disallow后面写禁止访问的路径前缀Allow则相反。比如User-agent: * Disallow: /admin/ Disallow: /api/private/ Allow: /public/这段规则的意思很直白所有爬虫不允许访问/admin/和/api/private/这两个目录但允许/public/目录。这里有个基础认知很多人以为robots.txt只能写禁止其实Allow是非标准但被广泛支持的扩展指令搜索引擎基本都认可它可以在Disallow的大范围里单独放行某些URL。还需要记住robots.txt文件内的路径是URL路径不是完整的URL。协议内容里不写域名和协议只写路径部分比如/category/page-1.html。文件本身的编码一般要求ASCII或者UTF-8我在实际项目中都统一用UTF-8无BOM格式保存避免部分解析器把BOM字符当成路径的一部分。2.2 通配符与匹配优先级80%的人在这里写错robots.txt的通配符支持情况一直是个容易混淆的点。严格意义上早期规范只支持空串和*作为User-agent的值路径匹配本身不支持正则。但主流搜索引擎在路径规则里扩展支持了*和$两个符号*匹配任意长度字符序列$匹配路径结尾。比如Disallow: /*.pdf$可以禁止抓取所有以.pdf结尾的URL。真正让人翻车的是匹配优先级。按现行的robots协议标准RFC 9309和主流搜索引擎的实现同一块规则里如果多条规则同时命中某个URL匹配逻辑是“最长匹配优先”也就是哪条规则的前缀能匹配的字符最长哪条生效如果两条规则匹配长度完全相同Allow优先于Disallow。举个具体例子User-agent: * Disallow: /report/ Allow: /report/2024/ Disallow: /report/2024/summary.pdf访问/report/2024/summary.pdf时三条规则都命中但Disallow: /report/2024/summary.pdf匹配的路径最长所以最终结果是禁止。访问/report/2024/data.xlsx时Allow: /report/2024/匹配长度最长所以允许。访问/report/2023/时只有/report/命中所以禁止。理解“最长匹配优先”之后很多诡异现象就能解释了——比如你写了Disallow: /a和Allow: /a/b爬虫抓/a/b/c时实际生效的是Allow: /a/b而不是低优先级的Disallow: /a。匹配过程中还有一个隐藏陷阱大小写敏感。路径是区分大小写的/Admin/和/admin/是两个完全不同的路径。如果你在robots.txt里写了Disallow: /Admin/而站点里实际路径是/admin/那这条规则形同虚设。2.3 容易忽略的语法细节与规范注释行以#开头可以放在任意位置但注意不要在路径中间插入注释否则路径会被截断。每行指令末尾不要画蛇添足加空格或回车换行符有些解析器会做trim有些不会稳妥起见统一不留尾随空格。文件大小方面规范建议robots.txt不要超过500KiB实际上绝大多数正常站点的robots.txt只有几百字节到几KB。如果文件太大爬虫可能只解析前面一部分就放弃导致后面的规则失效。我还见过一些站点把海量禁止路径全部塞进去维护很痛苦结果部分搜索引擎只读取了开头规则。robots.txt里还允许出现Sitemap:指令和一个对应的值用来指向站点地图的URL。它不隶属任何User-agent块写在文件任意位置都可以。搜索引擎看到这个指令会主动去拉取Sitemap文件了解站点URL结构对收录效率有直接帮助。我个人建议在robots.txt最后加上一行Sitemap: https://yourdomain.com/sitemap.xml。另外有一个叫Crawl-delay的扩展指令许多但不是所有爬虫支持。它用来告诉对方两次请求之间的最短间隔秒数比如Crawl-delay: 10表示希望爬虫每10秒请求一次。注意如果某个爬虫不支持这个指令它会直接忽略因此不能把Crawl-delay当成可靠的限速工具服务器层的限流才是兜底方案。3. 实战从零配置一份robots.txt并完成校验3.1 先盘点站点结构再动笔很多人的第一份robots.txt是抄来的这其实没问题但抄之前至少要搞清自己站点有哪些路径。我习惯先做一份简单的站点清单统计站点的目录结构哪些是面向用户的核心栏目哪些是内部后台、接口、临时文件目录。分类的时候重点考虑三个问题。第一核心内容路径一定要对搜索引擎开放。比如文章详情页、产品页、分类列表页这类页面是索引的资产屏蔽了等于不要流量。第二非必要路径要坚决关闭。后台管理路径、用户中心、登录接口、购物车会话页、测试环境页面、临时生成的导出文件这些对搜索用户没有价值还占用抓取配额应该屏蔽。第三注意动态URL和带参数的URL。很多老站点的URL带有?id123sortasc一类的查询参数如果不做限制爬虫会重复抓取大量内容相同的URL造成抓取浪费。针对这种情况可以在robots.txt里用*通配符把带参数的地址统一屏蔽。盘点完成后再决定分几个User-agent块。如果站点没有特殊诉求写一个User-agent: *的全局块就够了。如果某些爬虫需要特殊处理比如某个内容平台机器人抓取力度太大可以单独为它的UA写一个块用更严格的Disallow限定范围。注意同一爬虫只匹配第一个出现的User-agent块后面的块不会合并所以不要把同一机器人的规则分散写在多个块里。3.2 一份可直接套用的robots.txt示例下面这份配置框架是我在一个中等规模内容站点上实际用过的结构加了注释方便理解User-agent: * Disallow: /admin/ Disallow: /login Disallow: /cart/ Disallow: /checkout/ Disallow: /account/ Disallow: /api/ Disallow: /tmp/ Disallow: /search Disallow: /*? Disallow: /user/ Allow: /public/ User-agent: SomeSpiderBot Disallow: / Crawl-delay: 30 User-agent: * Disallow: /feed/ Sitemap: https://yourdomain.com/sitemap.xml拆开看几处关键决策。Disallow: /*?用来屏蔽所有带问号的URL也就是带查询参数的那批动态页这一条对控制重复抓取非常有效。Allow: /public/是给那些虽然在Disallow范围之外、但希望明确放行的静态资源目录。SomeSpiderBot那个块是给某个抓取力度特别大的机器人单独设置的Disallow: /等于告诉它整个站都不欢迎Crawl-delay: 30进一步降低它的请求频率。这里要提醒一点最后那个User-agent: *块里写了Disallow: /feed/但按照规范前面的User-agent: *块已经声明了全局规则后面的这一个*块对同属“未指名爬虫”的机器人并不会生效。为什么会这样写我实际是想给“已经在上一个块匹配到的、但不属于任何已命名机器人”的那部分做一个补充声明虽然语义上覆盖不完全但它不影响关键路径。更严谨的写法是把所有全局规则合并成一个*块。所以上面这份文件更适合做模板实际部署前建议按自己站点的结构重新整理别把规则拆得过于零散。3.3 配置好之后的验证与线上校验写完文件后第一步用curl模拟爬虫的行为确保文件可以正常访问并返回200状态码curl -i https://yourdomain.com/robots.txt输出里应看到HTTP/1.1 200 OK正文内容就是刚编辑好的规则。如果返回404或500问题出在服务器配置或文件路径上爬虫会认为没有任何限制。第二步做规则语义验证。主流搜索平台的站长工具里都有robots测试功能可以输入一个具体URL查看它最终命中的规则是允许还是禁止。这类工具能直接给出匹配到的规则行非常直观。没有站长工具的情况下可以自己写一个小脚本把robots.txt规则解析后用最长匹配优先的算法去模拟几个关键URL尤其是那些边界路径。第三步是观察日志验证。文件上线后在爬虫的抓取日志里对比规则变更前后的请求分布。比如新增了Disallow: /tmp/就该看到指向/tmp/目录的请求数量逐步降为0。需要注意的是抓取方不一定会立刻丢弃已经排入队列的URL所以这个降为0的过程可能需要几小时甚至几天不要刚上线几分钟就下结论。4. 配置完robots.txt就结束了吗配套管控方案4.1 meta robots标签与X-Robots-Tag响应头robots.txt管的是“抓取”而“索引”是另一件事。很多站点把不想被搜索收录的页面写进robots.txt结果页面确实不被抓了但之前已经被抓取收录的页面并不会自动从搜索结果里消失——因为robots.txt管不到索引。要管控某个具体页面是否被收录应该用页面级的meta robots标签或者HTTP响应头里的X-Robots-Tag。meta robots标签放在HTML的head里常见写法是meta namerobots contentnoindex, nofollow。noindex表示不要把这个页面放进索引库nofollow表示不要继续跟踪页面上的链接。这里特别建议组合使用仅设置nofollow还允许索引仅设置noindex可能还允许抓取链接关系明确表达“别收录”就直接两个都写上。X-Robots-Tag则更适合动态页面、接口、静态文件这类不方便改HTML的情况由服务器在响应头里下发。比如X-Robots-Tag: noindex。还有一种场景是防止内容被快照转载可以在响应头里加noarchive告诉搜索引擎不要保存页面快照。这套组合拳的优势在于粒度极细可以精确到单个URL而robots.txt只能按路径前缀做粗粒度控制。实际操作中我摸索出一个经验对要删除出索引的URL优先用meta robots或X-Robots-Tag标noindex同时不要把robots.txt里的对应路径Disallow掉。因为搜索引擎需要重新抓取一次页面才能看到noindex标签如果这个路径在robots.txt里被禁止抓取它就永远看不到这个指令URL就会一直被收录。4.2 抓取速率与抓取配额的协同管理robots.txt的Disallow能挡住“该抓的别抓”但控制不了“允许抓的路径被疯狂抓”。对允许抓取的页面还需要关注抓取速率和抓取配额。抓取配额crawl budget常说的抓取预算是搜索引擎在某个站点上愿意投入的总抓取资源它和站点规模、内容更新频率、页面质量、服务器响应速度都有关系。响应时间越快、有效内容越多、无效URL越少配额就越充足、抓取效率越高。所以清理robots.txt里的无效路径、减少重复URL本质上是在帮助搜索引擎把有限的配额用到真正有价值的页面上。速率控制则要从两头做。一头是爬虫侧的自觉在robots.txt里声明Crawl-delay适合still支持该指令的爬虫。另一头是站点侧的强制如果某个IP段或某个UA的请求速率超过阈值在Nginx或WAF层直接拦截或限速。我个人习惯在访问日志里按UA做聚合统计重点观察几个头部爬虫的日请求量一旦某个爬虫请求量出现异动就临时加一条server级别的访问规则进行限制。这种方法不依赖爬虫是否自觉是更可靠的兜底方案。4.3 Sitemap提交与机器人友好度的整体设计robots.txt里写Sitemap地址只是第一步真正提升收录效率的是稳定的Sitemap更新机制。Sitemap里应该只放“需要被收录”的URL存放后台地址、登录页、搜索结果页的URL属于自找麻烦。Sitemap文件本身要输出正确的Lastmod时间不要每次都返回相同时间戳搜索引擎判断页面更新频率时这个字段是重要依据。把这一整套东西想清楚之后站点的“机器人友好度”就上来了robots.txt定义了抓取边界meta robots和X-Robots-Tag定义了索引边界Sitemap负责告诉搜索引擎哪里有新内容服务器限速保障了资源稳定性。任何一个环节缺失都可能在日志里体现为“抓取量暴涨但索引量不涨”或者“核心页面迟迟不被抓取”。5. 爬虫不听话常见问题排查与实操记录5.1 规则写对了但爬虫不遵守怎么办明明robots.txt里已经Disallow: /tmp/日志里却还是看到爬虫在抓取/tmp/下的文件。遇到这种情况先别急着骂爬虫按下面几个方向排查。先确认robots.txt是否真正生效。用浏览器直接访问https://yourdomain.com/robots.txt看内容是不是线上最新版本。很多站点上了CDNrobots.txt被CDN缓存了老版本爬虫拿到的是之前的规则当然不会执行新配置。这时需要刷新CDN缓存或者给robots.txt设置较短的缓存时间。再确认规则是否匹配到了真实路径。注意URL里大小写、末尾斜杠、百分号编码的差异。比如站点的真实路径是/tmp%2Fdownload/robots.txt里写的是/tmp/download/两者不匹配。建议从访问日志里复制几条真实请求路径逐字比对而不是凭印象判断。排除这些之后如果某款爬虫仍然无视robots.txt很可能它本身就属于不遵守协议的采集器。这类机器人没有谈判空间直接在服务器防火墙或WAF里按UA、IP段封禁同时开启速率限制。我的一个经验是封禁要按IP段做因为很多采集工具会轮换IP单纯封单个IP效果很差。5.2 路径大小写与编码导致的误伤robots.txt匹配是大小写敏感的这是最常见的误伤来源。假设站点之前有一批链接是/Product/123后来重写成/product/123但robots.txt里还留着Disallow: /Product/那重写后的页面反而被放行了该屏蔽的没屏蔽反过来也可能出现新路径被老规则误杀的情况。建议所有路径规则都按站点当前真实使用的URL写不能凭记忆。还有一类问题是URL编码。路径里如果包含中文、空格、特殊字符在robots.txt里应该写URL编码后的形式比如空格写成%20。但有些爬虫在解析robots.txt时会把%20解码成空格再匹配有些则直接拿编码后的字符串做比较行为不一致。为了避免问题我在配置时尽量不把带特殊字符的路径直接写进robots.txt而是改用更高层级的目录前缀或者干脆用meta robots标签控制这一类页面。5.3 改动后不生效缓存与生效时机还有一个高频问题是“改了robots.txt为什么一周了还是老样子”。除了CDN缓存搜索引擎对robots.txt本身也有缓存机制有的爬虫会缓存数小时到数天不是每次抓取都重新拉取。这种延迟是正常的不要反复改文件折腾。确认思路是这样先用curl看线上文件内容确认服务器侧已经更新。然后看爬虫日志里请求robots.txt的时间戳和频率如果好几天都没有请求那说明抓取方还没触发重新读取如果每天都在请求但内容还是旧的多半是中间层缓存。我的处理办法是在服务器配置里对robots.txt设置Cache-Control: no-cache之类的响应头让中间缓存尽量失效但最终效果还是取决于爬虫自身的缓存策略急不来。5.4 常见问题速查表下面整理了一份我在工作里反复用到的问题排查表按频率排序症状可能原因解决方案爬虫仍在抓取已Disallow目录规则未生效、CDN缓存旧文件、路径大小写不匹配用curl核对线上文件比对真实URL刷新缓存页面被收录但robots.txt禁止了之前抓取时未被禁止robots.txt不影响已收录页面改用meta robots的noindex或提交索引移除请求带参数的URL被抓取过多没有屏蔽动态URL增加Disallow: /*?规则清理无效参数某爬虫请求量异常大对方忽略robots.txt或Crawl-delay在WAF/IP层面限速或封禁按IP段操作抓取量大但收录量不涨页面质量低、无有效Sitemap、重复URL多检查Sitemap有效性清理重复内容优化页面加载速度robots.txt不小心屏蔽了核心页面规则过度宽泛或通配符理解错误用最长匹配规则单独放行核心路径或临时删除整条规则最后说一点我个人的习惯robots.txt不是一次写好后就能放手不管的静态文件。站点每次改版、换路由、加栏目我都会把线上robots.txt重新过一遍配合访问日志观察抓取频率的变化。这份文件确实是最轻量级、最公开的治理手段但它也有边界——它只是君子协议不能替代页面级的索引控制更不能替代服务器安全策略。只有搞清楚它的能力和局限才能在实际运维里把它用到恰到好处。