站点只有几百个 URL 时,一个 sitemap.xml 写到尾就够了。当 URL 涨到几万、几十万,单文件会撞上协议的硬限制,这时候需要的是 Sitemap 索引文件(sitemapindex),把 URL 拆成若干份子 Sitemap 分批交给蜘蛛。
单个 Sitemap 的两条硬上限
按主流搜索引擎的 Sitemap 协议约定,单个 Sitemap 文件有两个限制:
- 最多 50,000 条 URL;
- 解压后体积不超过 50MB(未压缩计算)。
容易踩的坑是:超限不是“只收录前 5 万条”,而是整份文件被判定为无效。一条 URL 都读不到,而且你在后台看到的往往只是一个状态标记,不会告诉你具体哪一行越界。提交前用脚本数一遍行数和字节数,比事后排查省事得多。
如果提交 .gz 压缩版本,体积按解压后的内容算,压缩只是省传输带宽,不会放宽上限。
Sitemap 索引文件怎么组织
索引文件本身不列具体 URL,只列子 Sitemap 的地址和各自的 lastmod。它的作用是让蜘蛛知道“这个站的地图有几张、每张什么时候更新过”。
关键决策是按什么维度切分。常见的几种:
- 按内容类型:商品、文章、问答各一份,便于分别观察抓取情况;
- 按栏目或目录:与站点自身的 URL 结构对齐,好维护;
- 按更新频率:高频更新的内容和一年不动的内容分开,这是最实用的一种;
- 按数量均分:纯粹为了让每份不超限,最省事但最难排查。
不管选哪种,切分维度要稳定。同一个 URL 不要这周在第一份、下周跑到第三份,否则子 Sitemap 的 lastmod 会频繁变动,管理员和蜘蛛都要多做无用功。
分片粒度:太细和太粗都有代价
分得太细,蜘蛛要先读索引、再逐个请求子文件,光是请求开销就翻了几倍;一个站有 300 个子 Sitemap,蜘蛛每天爬一圈索引本身就要消耗不少抓取次数。
分得太粗,单份文件里混着高频和低频内容,每次小改动都会让整份文件的 lastmod 变化,蜘蛛无法判断到底哪部分更新了。
一个可用的折中:按更新频率切分,让每小时更新的内容和每月更新的内容各自成片;每份控制在几千到几万条 URL,体积留出余量。这样 lastmod 才有区分度,蜘蛛复查的节奏也更贴近内容实际的变化速度。
Sitemap 是候选清单,不是入口
需要反复提醒的一点:Sitemap 里的 URL 只是候选。蜘蛛读到它,只代表知道了这个地址存在,是否抓取、什么时候抓,仍然取决于内链入口、页面权重和抓取预算。
如果某个 URL 只出现在 Sitemap 里、站内没有任何链接指向它,它大概率会长期躺在队列里不动。Sitemap 与内链是两套并行的发现路径,前者负责“告知”,后者负责“证明它值得抓”。
分片常见的失效原因
- 索引文件里又嵌了索引文件,层级错了;
- 子 Sitemap 返回 301、403 或 5xx,蜘蛛拿到的是无效响应;
- robots.txt 里误屏蔽了子 Sitemap 所在目录,蜘蛛连文件都取不到;
- 所有分片的 lastmod 写成同一个时间,等于没有信号;
- Sitemap 里塞进了 404、重定向或已下线的 URL,白占额度;
- URL 的大小写、转义写法与站内实际链接不一致,同一页面被当成两个地址。
怎么验证分片是否真的被读到了
提交只是第一步,验证靠日志:
- 在服务器日志里筛出蜘蛛对 sitemap 相关路径的请求,看索引文件和子文件的请求频率是否正常;
- 统计每个子 Sitemap 被请求的比例,找出长期没人碰的那几份;
- 对没人碰的分片逐一检查:是否被 robots 挡了、是否返回非 200、里面的 URL 是不是早已失效;
- 观察服务器在蜘蛛集中抓取 Sitemap 时段的响应,5xx 会让它暂时降低对这批文件的兴趣。
把 Sitemap 当成一张地图:地图画得再全,路还是得靠内链和服务器响应真正铺出来。
几条实践建议
- 先数 URL 总量再决定是否分片,不要等超限了才动手;
- 分片维度选好后保持稳定,不要频繁重组;
- 高频内容单独成片,让 lastmod 有实际含义;
- 定期清理 Sitemap 里的失效 URL,保持清单干净;
- Sitemap 之外,同步维护好内链和入口页,两件事要一起做。