当站点 URL 数量增长到几千甚至几十万,单个 Sitemap 文件就很难承载,分片和索引文件随之成为必须维护的基础设施。切分本身并不复杂,麻烦的是分片之后如何保持一致、如何与内链和抓取日志对得上。
什么时候需要分片
常规做法是单个 Sitemap 不超过 5 万条 URL、未压缩体积不超过 50MB,超过就拆成多个子地图,再用一个索引文件(sitemapindex)把它们列出来。索引文件本身也有类似的条数上限,理论上可以再套一层,但实际运营中很少需要超过两级。
判断是否要分片,看的不是感觉上的多与少,而是实际的生成和维护成本:一次性生成十万条 URL 的 XML 会让脚本跑很久,出错后重跑代价高;分片之后可以按模块增量更新,某个文件出问题也只影响那一部分。
分片维度的选择
常见的切分方式有几种,各有取舍:
- 按内容类型:文章、商品、分类、标签各一份。好处是不同类型的更新频率和抓取价值可以分开管理。
- 按更新时间:热数据单独一份,历史数据归档成几份。适合新闻、电商这类时效性强的站点。
- 按 ID 区间或数量:最机械,结构统一的大站用起来省事。
如果站点同时存在需要频繁重抓的 URL 和基本不再变化的 URL,按内容类型加更新时间组合切分通常更好用,因为蜘蛛对不同子地图的重访节奏本来就不一样。
索引文件保持简洁
索引文件里每条记录只需要 loc 和可选的 lastmod,不必塞入额外字段。文件小、结构稳定,比堆砌信息更有价值。索引文件一般放在根目录,并在 robots.txt 中声明位置。
更新节奏与一致性
分片之后最容易出问题的是更新不同步:主站已经删掉的 URL 还留在旧子地图里,新上线的页面进了索引却没有归入任何子地图。建议把生成流程做成可重复执行的定时任务,每次重新生成全部受影响的分片,而不是在旧文件上手动追加。
几个常见的核对点:
- 子地图里的 URL 是否都能返回正常状态码,是否还残留已被 404 或 410 处理的历史链接。
- lastmod 是否来自真实的内容变更时间,而不是每次生成时统一刷新成当前时间。统一刷新等于把这个字段作废。
- 索引文件里列出的子地图地址是否都可访问,压缩文件(.gz)的编码和 Content-Type 是否正确。
- 分片数量变化后,索引文件是否同步更新,旧的子地图地址是否已经被移除而不是继续返回旧内容。
与抓取日志的交叉核对
Sitemap 只是告诉蜘蛛有哪些 URL,它并不保证这些 URL 会被抓取。要判断分片是否有效,得回到抓取日志:统计每个子地图中被抓取的 URL 比例、抓取间隔、状态码分布。如果某个分片长期没有抓取记录,可能是文件过大、内容价值偏低,也可能是它列出的 URL 在内链中几乎没有入口。
这时候可以做一个简单对比:把 Sitemap 里的 URL 集合与站内可点击到达的 URL 集合求差集。差异部分如果数量很大,说明站点对 Sitemap 的依赖过重;如果差异很小,Sitemap 更多是辅助作用,重点应该放在内链结构本身。
分片不是把文件切小就完事,它是让 URL 清单可维护、可核对的一种组织方式。任何一份子地图,你都应该能回答三个问题:里面有哪些 URL、它们现在是什么状态、上一次真正更新是什么时候。
最后提醒一点:Sitemap 的提交和更新属于基础工作,它能改善蜘蛛发现 URL 的效率,但站点能否被正常抓取和展示,取决于内容质量、内链结构和服务器可用性等综合因素,不宜把全部希望压在这份文件上。