当一个站点的 URL 数量从几百涨到几万、几十万,单个 Sitemap 文件很快就会顶到上限。Sitemap 协议中,一个文件最多容纳 50000 个 URL,未压缩体积不超过 50MB。超过这个量级,就需要 sitemap index(索引文件)把多个分片串起来。这一步看起来只是“拆文件”,但它实际上会影响蜘蛛发现 URL 的节奏、单个文件的抓取成本,以及更新信号的准确度。
为什么要拆:三个现实问题
第一是解析成本。蜘蛛每次读取 Sitemap,都要把整个文件下载下来并解析。如果一个大文件里绝大多数 URL 长期没有变化,这部分消耗就偏向浪费。拆成小块之后,蜘蛛可以按需读取变化更频繁的分片。
第二是更新信号。分片之后,每个分片可以有自己的 lastmod,越贴近该批 URL 的真实变更时间,信号越有意义。所有分片写同一个时间,等于告诉蜘蛛“全站每天都在变”,久而久之这个字段就失去参考价值。
第三是故障范围。某个分片因为体积过大而超时、格式出错或返回异常,只会影响这一批 URL,不会把整份地图拖下水。
分片常见的几种切法
按内容类型切是最直接的做法,比如文章、商品、分类、标签各占一个分片。好处是更新频率接近的 URL 聚在一起,坏处是当某一类数量暴涨时需要重新调整。
按更新时间切更适合内容持续产出的站点,例如按月或按季度生成增量分片,历史内容放进归档分片,这类分片几乎没有变化,蜘蛛不需要反复读。
按目录或多语言目录切,适合结构本来就分层的站点,分片地址和站点结构对应,排查问题时也容易定位。
需要注意的是不要切得太碎。几百个小文件意味着蜘蛛要额外抓取索引文件并逐条请求,而每次请求都要占用抓取资源。通常每个分片放几千到几万条 URL 比较稳妥,具体取决于站点被抓取的频率。
索引文件本身的写法要点
- 索引文件只能引用 Sitemap 文件,不要再引用另一个索引文件,嵌套层级对蜘蛛并不友好。
- 索引里的 lastmod 可以填写,用来表示该分片内容的整体变更时间,但同样要真实。
- 索引文件地址要固定,改名或换目录后记得同步更新 robots.txt 和后台提交记录。
- robots.txt 中的 Sitemap 指令指向索引文件即可,不必把几十个分片地址一一列出。
分片后容易踩的几个坑
- 所有分片的 lastmod 都写成同一天,等于没有提供任何变化信息。
- 分片 URL 返回 200,但内容是一个空列表,蜘蛛会认为该分片有效却无内容。
- 分片被 CDN 或缓存层保存太久,新 URL 迟迟不出现,抓取节奏被拉长。
- 分片里混入大量 301、404 或 noindex 的地址,占用了本该留给有效页面的抓取机会。
- 分片里包含被 robots.txt 屏蔽的路径,蜘蛛读取地图时会直接跳过这些条目。
分片与抓取调度
蜘蛛会根据自身抓取能力和站点优先级决定什么时候来读 Sitemap。把变化频繁的内容单独放进一个分片、把稳定的历史内容放进另一个分片,能减少蜘蛛每次重新解析的量。同时也要清楚,Sitemap 主要解决“发现”问题,让蜘蛛走到站点深处,仍然依赖内链结构。分片做得再好,也不该成为 URL 的唯一入口。
上线前的检查清单
- 逐个访问分片 URL,确认返回 200 且内容是结构正确的 XML。
- 检查每个分片的 URL 条数与字节数,都在协议限制以内。
- lastmod 使用标准格式,并与页面的真实更新时间对得上。
- robots.txt 中只保留索引文件地址,且域名与协议一致。
- 提交索引文件后,观察后台的抓取统计,确认分片被正常读取。
分片的意义不是把文件变小,而是让蜘蛛用更少的请求,拿到更准确的变化信息。
把 Sitemap 当成一份需要长期维护的清单,而不是一次生成就再不过问的文件,蜘蛛对站点的理解会更稳定一些。