站点小的时候,一個 sitemap.xml 就能装下全部 URL。等到文章上千、栏目几十個,單文件要么体积超标,要么每次生成都拖慢服務器。這时候就要用 sitemap 索引文件(sitemap index)把地图拆成多份。拆得合理,蜘蛛讀取顺畅;拆得随意,反而制造新的抓取障碍。
什么时候该拆分
常见的两個硬限制:單份 sitemap 里的 URL 數量不超過 5 萬條,未压缩体积不超過 50MB。接近任意一條,就该考虑分片。還有一種更隐蔽的情况:站点 URL 只有几千條,但每次請求 sitemap 都要實时查库拼装,接口耗时两秒以上——問题不在數量,而在生成方式。
三種常见的分片切法
- 按栏目或目錄切:文章、商品、問答各自一份,结构清晰,新增栏目时改動小。
- 按更新時間切:把近期更新的 URL 單獨放一份,蜘蛛每次優先讀這份,老内容放歷史分片,讀取频率降低。
- 按内容類型切:頁面、图片、视频、新闻分別成文件,各自遵循對應的格式要求,避免混在一起導致解析报错。
三種可以组合使用。切分的目的不是好看,而是让蜘蛛用更少的請求拿到更准确的信息。
索引文件的寫法與入口
索引文件本身只包含各個分片的地址和最後修改時間,不列具体 URL。它同样受 50MB 限制,但一般遠達不到。關键是入口要让蜘蛛找得到:在 robots.txt 里用 Sitemap 指令声明索引文件地址,同时保證分片 URL 返回 200,且寫的是完整的绝對地址。
多級索引(索引指向索引)在規范里是被允许的,但层級越深,中間环节出错的机會越多。两层通常够用。
lastmod 別当摆设
lastmod 寫“今天”最省事,也是最容易被忽略的做法。如果每份分片的最後修改時間每天都在變,蜘蛛會認為整站天天在更新,久而久之對這個字段失去信任。建议让 lastmod 反映内容真實改動的時間,批量改模板導致的時間戳變動,可以在生成逻辑里排除。
動態生成的两点注意
- 加缓存:把生成的 sitemap 落盘或放 CDN,設定合理的過期時間,別让每次蜘蛛訪問都打資料库。
- 超时兜底:接口慢于几秒时返回上一次的缓存版本,也好過返回 500 或空文件。
分片之後容易踩的坑
- 索引文件里指向了已刪除或改名的分片,返回 404,却没被及时發現。
- 分片返回 200,但内容是空的或只有 XML 头,蜘蛛讀到的是“這一批没有 URL”。
- 分片内混入了 301、404、noindex 的地址,等于把無效路径反复送出去。
- 用 gzip 压缩後没設定正确的 Content-Type,解析可能直接失敗。
- 分片數量太多太碎,几千個 URL 拆成几十個文件,反而增加讀取成本。
Sitemap 只是补充,不是替代
Sitemap 解决的是“告诉你這里有哪些 URL”,它不解决“這個 URL 值不值得抓”。頁面的内鏈位置、被引用的次數、内容本身的质量,才是决定抓取優先級的部分。
把 URL 寫進 sitemap,不意味着它會被抓取,更不意味着會被收錄。它的價值在于降低蜘蛛發現不了的概率,尤其是层級深、内鏈少的頁面。如果一篇文章在任何列表頁都找不到入口,只存在于 sitemap 里,即使被抓到,後續的重新抓取也會缺少触發路径。
一個简單的自查顺序
- 打開索引文件,逐個点開分片,確認都返回 200 且内容非空。
- 抽查分片里的 URL,確認不是 404、301 或已设 noindex。
- 核對最後一层的分片數量與 URL 總量是否對得上。
- 看服務器日誌里 sitemap 相關請求的响應時間與狀態碼。
- 確認 robots.txt 里的 Sitemap 指令没有被注释掉或寫错域名。
這几步花不了太多時間,但能挡掉大部分“sitemap 提交了却没動静”的情况。真正影响抓取效率的,往往不是地图本身,而是地图背後那些生成不稳、地址失效、更新失真的细节。