搜尋抓取

Sitemap 分片與压缩:URL 清單太大时怎么交给蜘蛛

当站点 URL 規模上萬,單個 Sitemap 的 5 萬條與 50MB 上限就成了硬约束。本文說明如何用索引文件组织分片、用 Gzip 压缩传輸,以及按栏目和更新频率切分的思路,並列出分片後容易踩的几個坑,帮助蜘蛛把 URL 清單讀全。

搜尋抓取

Sitemap 分片與压缩:URL 清單太大时怎么交给蜘蛛

站点 URL 數量上萬以後,Sitemap 就不再是一個文件能装下的事。协议對單個 Sitemap 有明确上限:5 萬條 URL、未压缩体积 50MB。超了不會报错,但多出来的部分會被直接忽略,等于白交。所以規模上去之後,分片和压缩不是優化技巧,而是必须做的事。

三條硬线先记住

  • 單個 Sitemap 文件:URL 不超過 5 萬條,未压缩体积不超過 50MB。
  • 索引文件(sitemapindex):最多收錄 5 萬個 Sitemap,同样受 50MB 限制。
  • 一個索引文件可以指向多個 Sitemap,但不能再套一层索引。

這三條是协议层面的约束,寫错了大概率不會立刻看到报错,但蜘蛛會安静地丢掉超出部分。所以每次生成 Sitemap 时,最好在程序里加一道校驗,超限就自動切分。

索引文件怎么寫

分片之後需要一個入口把清單串起来,這就是 sitemapindex。它里面只放 <sitemap> 节点,每個节点一個 <loc>,可選的 <lastmod>。常见错誤是把 <url> 标簽混進索引文件,或者索引和分片互相引用,形成循环。

索引文件只负责指路,不负责列 URL。职责混在一起,出問题时最难排查。

压缩能省什么

Sitemap 支持 Gzip 传輸,把文件命名為 .xml.gz 即可。需要注意的是,限制按未压缩体积計算,压缩只是减少传輸带宽和下载耗时。對蜘蛛来说,一個 2MB 的压缩包比 20MB 的纯文本文件更容易在短時間内讀完,這在實际抓取中是有意义的差別。

但压缩後別忘了几件事:索引文件里的 <loc> 必须指向压缩後的真實地址;服務器要正确返回 Content-Type: application/x-gzip(或 application/gzip),並且不能對 .gz 文件再做一层传輸压缩,否則容易解压失敗。

怎么切分才合理

切分方式没有唯一答案,但下面几種比“随机每 5 萬條切一刀”更好维護:

  1. 按栏目切:文章、商品、分類、标簽各一個文件。某個栏目出問题,影响范围可控。
  2. 按更新频率切:高频更新的新闻、商品價格單獨成片,低频的静態頁另一片。這样 lastmod 的信号更干净。
  3. 按語言或地区切:多語言站点按目錄划分,便于分市场提交和統計。
  4. 保持归属稳定:同一個 URL 尽量長期待在同一個分片里,频繁搬家會让抓取統計對不上帳。

几個容易踩的坑

  • 分片文件的 <loc> 用相對路径。必须是完整绝對地址,含协议和域名。
  • 索引文件里寫 <url> 标簽,或者索引指向索引。
  • .gz 文件名和索引里寫的地址不一致,等于交了一份讀不到的清單。
  • 全站所有 URL 的 lastmod 都填成同一個生成時間。這個字段是给蜘蛛判断“值不值得重抓”的參考,全站齐刷刷一個時間,等于没有信息。
  • 分片文件没有對外可訪問,被權限、伪静態規則或 CDN 缓存策略挡住,蜘蛛下载返回 403 或 404。

交出去之後做什么

Sitemap 是發現入口,不是抓取指令。提交之後要做的是核對:在服務器日誌里看蜘蛛有没有真的去取這些分片文件,返回碼是不是 200,取完之後是否顺着里面的 URL 走進来。如果日誌里只看到取 Sitemap,却看不到後續的頁面抓取,問题往往不在 Sitemap 本身,而在頁面层的可達性、响應速度或 robots 規則。

另一件值得做的事是定期巡检:分片里是否存在大量 404、301 或者 noindex 的 URL。清單里混進太多無效地址,會稀释這份文件的價值,也會让蜘蛛多跑一趟空路。保持 Sitemap 與站内實际结构一致,比追求條數更重要。