< BACK 复古卡片索引柜抽屉敞开,温暖的钨灯照射,浅景深,35mm胶片颗粒

网站地图索引文件:突破50,000个URL的站点地图扩展指南

回到2021年,我接手了一个有140,000个产品URL的WooCommerce网站,单个sitemap.xml恰好在50,000个条目处达到上限,而客户搞不明白为什么Google Search Console只显示了他们网页的一小部分被索引。网站地图文件就这样... 停止了。没有错误。没有警告。只是无声地被截断了。这种情况会让你在排名上付出代价,却永远不会发出任何信号表明有问题。

如果你的网站正在增长到50,000个URL以上,这篇文章是你在撞到这堵墙之前必须要读的。

50,000个URL限制的原因

由Google、Bing和其他搜索引擎共同维护的Sitemaps协议对单个网站地图文件设置了两个硬性限制:最多50,000个URL,未压缩大小不超过50MB。这些不是建议。Googlebot会在达到其中任一限制时停止解析该文件。Sitemaps protocol, maintained jointly by Google, Bing, and others, sets two hard constraints on a single sitemap file: no more than 50,000 URLs, and no larger than 50MB uncompressed. These aren't suggestions. Googlebot will stop parsing the file at whichever limit it hits first.

说实话,50MB的上限很少成为问题。大多数URL都足够短,以至于你需要极其冗长的路径才能在达到URL计数限制之前触发文件大小限制。50,000个URL的上限才是让人受挫的地方。

那么当你的商品目录、博客归档、用户生成内容部分超过这个阈值时,你该怎么办?使用网站地图索引文件。

网站地图索引文件到底是什么

概念很简单。与其创建一个包含所有URL的单一网站地图,不如创建一个父XML文件,指向多个子网站地图。每个子网站地图最多可以包含50,000个URL。索引文件本身可以引用最多50,000个子网站地图。所以理论上限是25亿个URL。你不会达到这个数量。

结构看起来像这样:

`` sitemap_index.xml ├── sitemap-posts-1.xml (最多50,000篇博客文章) ├── sitemap-posts-2.xml (溢出文章) ├── sitemap-products-1.xml (最多50,000个产品) ├── sitemap-products-2.xml (溢出产品) └── sitemap-pages.xml (静态页面) `` sitemap_index.xml ├── sitemap-posts-1.xml (up to 50,000 blog posts) ├── sitemap-posts-2.xml (overflow posts) ├── sitemap-products-1.xml (up to 50,000 products) ├── sitemap-products-2.xml (overflow products) └── sitemap-pages.xml (static pages) ``

索引文件使用<sitemapindex>作为根元素,而不是<urlset>。每个子文件被包装在<sitemap>标签中,包含指向子文件的<loc>,以及可选的<lastmod>时间戳。<sitemapindex> as the root element instead of <urlset>. Each child is wrapped in a <sitemap> tag with a <loc> pointing to the child file, and optionally a <lastmod> timestamp.

你提交给Google Search Console的是索引文件URL,而不是每个单独的子文件。一次提交,唯一的信息源。

如何智能地分割你的URL

这是大多数教程出错的地方。它们说"只需将你的URL分成50,000个一组",然后就停止了。但分割边界对可维护性和Googlebot的爬取逻辑都很重要。

我按内容类型分割,而不是按任意数字。总是这样。每次都是。

先按内容类型拆分

  • 产品放在自己的网站地图系列中(sitemap-products-1.xml、sitemap-products-2.xml)sitemap-products-1.xml , sitemap-products-2.xml)
  • 博客文章放在自己的系列中
  • 分类和标签页面放在一起(它们是导航性的,视为一个组)
  • 静态页面(关于、联系、着陆页)放在一个文件中,通常远低于 1,000 个 URL

为什么这很重要?因为当产品数据库进行批量更新时,只需要重新生成产品网站地图。你不会失效并重新生成混合了产品和博客文章的单一文件。Googlebot 也往往按顺序抓取网站地图,所以按类型分组能给它一个更清晰的信号,告诉它即将遇到什么类型的内容。

然后在每种类型中分页

一旦某个内容类型超过 50,000 个 URL,就对其进行分页。从一开始就使用一致的命名约定。我使用 sitemap-{type}-{page}.xml。不要在文件名中使用日期。我在 2019 年的一个新闻网站上犯过这个错误,最后得到了像 sitemap-articles-2019-march.xml 这样的文件名,一旦我们需要重新生成历史内容,这些就变得完全没有意义。坚持使用数字分页。sitemap-{type}-{page}.xml . Don't use dates in the filename. I made that mistake on a news site in 2019 and ended up with filenames like sitemap-articles-2019-march.xml that became completely meaningless the moment we needed to regenerate historical content. Stick to numbered pages.

保持 lastmod 的准确性

子网站地图中的 <lastmod> 元素应该反映内容实际最后修改的时间,而不是你重新生成网站地图的时间。我见过一些设置,其中每次重新生成都会用今天的日期标记每个 URL。这会让 Googlebot 学会忽略你的 lastmod,因为该信号只是噪音。使用你的 CMS 实际修改的时间戳。在 WordPress 中,那就是 wp_posts 表中的 post_modified_gmt。<lastmod> element in your child sitemaps should reflect when the content was actually last modified, not when you regenerated the sitemap. I've seen setups where every regeneration stamps every URL with today's date. That trains Googlebot to ignore your lastmod entirely because the signal is noise. Use your CMS's actual modified timestamp. In WordPress, that's post_modified_gmt from the wp_posts table.

工具:大规模下实际有效的方案

对于WordPress网站(这是我们在Seahawk建设的大部分项目),我实际使用的选项是:

  1. Yoast SEO在单个文章类型超过1,000个URL后会自动处理网站地图索引。它生成整洁、分段的文件。但默认批处理大小是每个子网站地图1,000个URL,这比较保守。你可以通过wpseo_sitemap_entries_per_page过滤器增加这个数字。在托管良好的服务器上,我通常会将其推至5,000。 handles sitemap indexes automatically once you have more than 1,000 URLs per post type. It generates clean, segmented files. But the default batch size is 1,000 URLs per child sitemap, which is conservative. You can filter that up with wpseo_sitemap_entries_per_page. I usually push it to 5,000 on well-hosted servers.
  2. Rank Math做法类似,对于哪些文章类型和分类法获得自己的子网站地图有更细粒度的控制。在最近一个拥有80,000个WooCommerce产品的客户网站上,Rank Math的开箱即用分段效果比Yoast更整洁。 does the same, with slightly more granular control over which post types and taxonomies get their own child sitemaps. On a recent client site with 80,000 WooCommerce products, Rank Math's segmentation out of the box was cleaner than Yoast's.
  3. 当网站具有不寻常的内容类型或插件生成的网站地图生成速度太慢时,我会采用WP-CLI自定义生成方案。我编写过的脚本直接查询数据库,将结果按10,000个为一组分页,将XML写入磁盘,最后写入索引文件。即使有200,000个URL也能在30秒内完成。关键是写入临时文件,然后原子性地将其移至目标位置,这样Googlebot永远不会访问到未完成的文件。 is what I reach for when the site has unusual content types or the plugin-generated sitemaps are too slow to generate. I've written scripts that query the database directly, paginate results in chunks of 10,000, write the XML to disk, and then write the index file last. Runs in under 30 seconds for 200,000 URLs. The key is writing to a temp file and atomically moving it into place so Googlebot never hits a half-written file.

对于非WordPress技术栈,Screaming Frog SEO Spider可以爬取你的网站并为你生成网站地图索引,但它更适合用作验证工具而不是生产环境的网站地图生成器。对于生产环境,应该从你的数据源生成网站地图,而不是从爬虫生成。爬虫会遗漏内容。Screaming Frog SEO Spider can crawl your site and generate a sitemap index for you, though it's better as a validation tool than a production sitemap generator. For production, generate sitemaps from your data source, not from a crawler. Crawlers miss things.

在Search Console中提交和验证

打开Google Search Console,进入网站地图报告,提交你的索引文件URL。只需一个URL。就这样。Google Search Console, open the Sitemaps report, and submit your index file URL. One URL. That's it.

提交后,等待24-48小时,然后检查两项内容:

  • 已提交与已发现。"已发现URL"的数量应该逐渐增加,趋近于你的实际URL数量。如果它早早就停滞不前,你可能存在爬虫预算问题或子网站地图格式错误。 The "Discovered URLs" count should be climbing toward your actual URL count. If it plateaus weirdly early, you likely have a crawl budget issue or a malformed child sitemap.
  • 单个子网站地图状态。Search Console 会显示每个子网站地图及其状态。如果某个子网站地图出现错误,你可以单独处理它而不影响其他的。这是索引结构被低估的优势。 Search Console will show you each child sitemap and its status. If one child is returning an error, you can isolate it without touching the others. This is the underrated advantage of the index structure.

Bing Webmaster Tools 的工作方式相同。提交索引文件,而不是子文件。只需两分钟。

我经常看到的常见错误

Seahawk 定期为代理机构审查网站。同样的网站地图错误一次又一次地出现。

网站地图中包含 noindex 的 URL。如果 URL 有 noindex meta 标签或 X-Robots header,它就不应该出现在你的网站地图中。句号。网站地图是对爬虫和索引的建议。包含 noindex URL 会浪费抓取预算并混淆信号。在任何重大网站上线前,我会快速使用 Screaming Frog 针对网站地图 URL 进行爬取,并筛选 noindex 响应。 If a URL has a noindex meta tag or X-Robots header, it should not be in your sitemap. Full stop. A sitemap is a recommendation to crawl and index. Including noindexed URLs wastes crawl budget and confuses the signal. I run a quick Screaming Frog crawl against the sitemap URLs and filter for noindex responses before any major site launch.

网站地图中的被阻止 URL。比 noindex 更糟:在 robots.txt 中被禁用但仍在网站地图中列出的 URL。Googlebot 能看到这个矛盾。它不会因此惩罚你,但这很不专业,也会浪费时间。 Even worse than noindex: URLs that are disallowed in robots.txt but still listed in the sitemap. Googlebot can see the contradiction. It won't penalise you for it, but it's sloppy and it wastes time.

添加新的子网站地图后没有更新索引文件。这听起来很明显,但自定义实现经常在这里出错。你添加了一个新的内容类型,生成了新的子网站地图文件,但忘记了在索引中添加 <sitemap> 条目。子文件存在于磁盘上,但没有任何东西指向它。我见过这种情况被忽视好几个月。 This sounds obvious but it trips up custom implementations. You add a new content type, generate a new child sitemap file, and forget to add the <sitemap> entry to the index. The child file exists on disk but nothing points to it. I've seen this sit unnoticed for months.

单独提交子网站地图而不是索引。如果你有 12 个子网站地图并且分别将全部 12 个提交到 Search Console,你就失去了组织上的优势。提交索引。让它级联下去。 If you have 12 child sitemaps and you submit all 12 to Search Console separately, you've lost the organisational benefit. Submit the index. Let it cascade.

抓取预算:更大的图景

网站地图索引文件直接关系到抓取预算管理。谷歌关于抓取预算的文档值得阅读,如果你在这个规模上操作的话。简短版本:Googlebot 每天在你的网站上花费的时间是有限的,一个结构良好的网站地图索引可以帮助它首先把时间花在你的最高优先级内容上。Google's documentation on crawl budget is worth reading if you're operating at this scale. The short version: Googlebot has a finite amount of time it'll spend on your site per day, and a well-structured sitemap index helps it spend that time on your highest-priority content first.

我在大型网站上将新更新的内容放在单独的子站点地图中。我做过的一些实现使用 sitemap-recent.xml,其中只包含过去30天内修改过的URL,每小时刷新一次。Googlebot会积极重新抓取这个文件。较旧的历史站点地图文件抓取频率较低,这是可以的,因为这些内容不会改变。sitemap-recent.xml that only contains URLs modified in the last 30 days, refreshed hourly. Googlebot recrawls that one aggressively. The older historical sitemap files get crawled less frequently, which is fine because that content isn't changing.

这不是什么技巧,只是让抓取信号与内容现实相符。

FAQ

一个站点地图索引文件最多可以包含多少个子站点地图?

该协议最多允许在单个索引文件中包含50,000个子站点地图。实际上,如果你接近这个数字,说明你有数亿个URL,并且面临大多数网站从未面临过的问题。对于绝大多数大型网站,你会有5到50个子站点地图。

我需要用gzip压缩我的站点地图文件吗?

你不需要,但对大文件来说值得这样做。一个50MB的站点地图用gzip压缩后会缩小到大约3-5MB。Googlebot无需任何配置就接受.xml.gz文件。大多数现代网络服务器在服务器级别启用gzip压缩后会透明地处理这个问题。对于生成到磁盘的静态文件站点地图,我会用gzip预压缩并直接提供.xml.gz。need to, but it's worth doing for large files. A 50MB sitemap compresses down to roughly 3-5MB with gzip. Googlebot accepts .xml.gz files without any configuration. Most modern web servers will handle this transparently if you enable gzip compression at the server level. For static-file sitemaps generated to disk, I pre-compress with gzip and serve the .xml.gz directly.

我应该在索引中包含图像或视频站点地图吗?

应该包含。如果你使用图像站点地图扩展或视频站点地图,它们可以作为子站点地图包含在同一个索引文件中。将它们保持在自己的子文件中,而不是将图像数据混合到标准URL站点地图中。这样可以保持文件较小,并且当媒体库更新时更容易只重新生成图像站点地图。

如果子站点地图返回404会发生什么?

Search Console 会在站点地图报告中标记该子文件为错误。Googlebot 仍然会处理索引中的其他子站点地图。它不会使整个索引失效,但只在该 404 子文件中列出的网址将无法通过站点地图被发现。请立即修复。即使修复后,该错误在 Search Console 的报告中仍会显示数周,这很烦人但无害。

我可以在小型网站上使用站点地图索引吗?

从技术上讲可以,但没有必要。在网址数少于 10,000 的情况下,增加的复杂性不值得。单个 sitemap.xml 更容易维护、更容易调试,并且工作效果完全相同。只在需要时使用索引文件,不要提前使用。

---

50,000 网址限制总是会让人措手不及,通常发生在最糟糕的时刻,比如产品发布前。一旦设置正确的索引结构,随着网站增长,你再也不必为此烦恼。花一小时设置是值得的。

< BACK