你一次发布了 50 篇新文章。一周后 Search Console 里 URL 数还是发布前那个数,site: 也搜不到新页面。build 成功了,sitemap 也在线上,但 Google 没注意到。
最快的解法(大多数情况): 确保每个新 URL 带有准确的 <lastmod>,确认 robots.txt 声明了 sitemap,然后打开 Search Console > Sitemaps 把 sitemap URL 重新 add 一遍强制重读。这覆盖了 Google 真正会响应的两个信号。不要再去用老的 google.com/ping 或 bing.com/ping——两个都已经停用了(下面细说)。
搜索引擎不会激进地拉 sitemap。重抓节奏取决于历史抓取行为、它看到的 lastmod 值,以及明确的重新提交。sitemap 存在 ≠ sitemap 被读过。
重要——ping 端点已经没了。 Google 在 2023 年 6 月废弃了
/ping?sitemap=端点;截至 2026 年 6 月它返回404。Bing 更早,2022 年就停了bing.com/ping(现在是410 Gone)。任何部署脚本里还在 curl 这些 URL 的,都是在做无用功。受支持的替代方案是:Google 走lastmod+robots.txt+ Search Console(手动或 API),Bing/Yandex/Seznam/Naver 走 IndexNow。
你属于哪一种?
| 症状 | 最可能的原因 | 跳转 |
|---|---|---|
线上 <url> 数比本地 build 少 | CDN 在发旧 sitemap | 原因 1 |
robots.txt 没有 Sitemap: 那一行 | sitemap 从没被声明 | 原因 2 |
| sitemap 列着,“Last read” 是几周前 | 没重新提交、变更信号弱 | 原因 3 |
新文章的 <lastmod> 是旧的或缺失 | 爬虫看到”没变化” | 原因 4 |
| index 里列的分片 404 | sitemap 索引和分片对不上 | 原因 5 |
sitemap 里有 URL 但每个都是 noindex | 抓取后被排除 | 原因 6 |
常见原因
1. sitemap 生成了但还在发旧版
build 写了新的 sitemap.xml,但 CDN 边缘缓存还在返回旧的。爬虫拉到旧 URL,新的没看到。
如何判断:curl -s https://yoursite.com/sitemap.xml | grep -c '<loc>' 数条目数,和本地 dist/sitemap.xml 对比。(用 <loc> 而不是 <url>;sitemap 索引文件用的是 <sitemap>/<loc>,根本没有 <url> 标签。)
2. robots.txt 没声明 sitemap 位置
robots.txt 没写 Sitemap: 那一行,爬虫除非你在 Search Console 显式提交,否则可能永远找不到 sitemap。Sitemap: 是每个引擎都会读的那一行 robots.txt 指令。
如何判断:curl -s https://yoursite.com/robots.txt | grep -i sitemap。输出为空就是没声明。
3. sitemap 当初提交过但之后没再提交
Google 会重抓提交过的 sitemap,但频率取决于观察到的更新节奏。历史上更新少的站,重抓间隔可能 1-2 周。重新提交不会强制索引,但会把文件重新排进 Googlebot 的下一轮抓取队列。
如何判断:Search Console > Sitemaps > 看 “Last read” 那一列。
4. lastmod 时间没更新
ping 端点没了以后,Google 明确依赖 <lastmod> 来安排对已知 URL 的重抓。如果你的 build 输出的是旧的或完全一样的 lastmod,爬虫看不到任何变化信号,就会把重抓往后排。Google 官方说法是:lastmod 只有在准确且可对照页面内容验证时才有用——假的”永远是今天”的时间戳会被忽略。
如何判断:打开 sitemap.xml,确认新文章有近期 <lastmod>,老文章的 lastmod 反映了最近一次真实编辑。如果每条都是同一个 build 时间戳,看 sitemap lastmod 永远是今天。
5. sitemap 索引和分片对不上
大站会用 sitemap index 指向多个分片(按版块或按语言)。新文章进了某个分片,但 index 还引着旧文件——或者某个分片返回 404——爬虫就发现不了新内容。
如何判断:curl -s https://yoursite.com/sitemap-index.xml 确认每个子 sitemap 都列出来且返回 200:
curl -s https://yoursite.com/sitemap-index.xml \
| grep -oE 'https://[^<]+\.xml' \
| while read u; do echo "$(curl -s -o /dev/null -w '%{http_code}' "$u") $u"; done
每一行都应该以 200 开头。
6. 新 URL 被 robots.txt 或 noindex 挡了
sitemap 列了 URL,但每个页面带 <meta name="robots" content="noindex">,或者在 robots.txt 里被 Disallow。爬虫抓到、看到排除标记就丢掉——Search Console 会报 Submitted URL marked 'noindex' 或 Submitted URL blocked by robots.txt。
如何判断:curl -s <new-article-url> | grep -i 'noindex' 不应该有命中。然后看 robots.txt 里有没有覆盖到新路径的 Disallow:。如果发现冲突,看 robots meta 和 sitemap 冲突。
动手前先确认
- 新文章在生产站上是真在线(用浏览器打开一篇,看源码)。
- 记下部署完成的时间——重抓的计时是从这里开始算的。
- 你对该属性有 Search Console 访问权(URL-prefix 属性和 Domain 属性有区别;sitemap 必须落在已验证的属性下面)。
需要收集的信息
curl -s https://yoursite.com/sitemap.xml | head -50的输出——前几条和结构。- 线上 sitemap 的
<loc>总数。 robots.txt内容。- Search Console > Sitemaps > 状态和 “Last read” 时间。
- Search Console > Pages(“网页索引编制”报告)> 新 URL 是不是落在 “Discovered - currently not indexed” 或 “Crawled - currently not indexed” 里。
一步步修复
Step 1:本地和线上的 sitemap 对一下
# 本地
grep -c '<loc>' dist/sitemap.xml
head -3 dist/sitemap.xml
# 线上
curl -s https://yoursite.com/sitemap.xml | grep -c '<loc>'
curl -s https://yoursite.com/sitemap.xml | head -3
数量应该一致。线上小于本地就是 CDN 缓存问题——按 CDN 重建后缓存过期 那篇去 purge,再复查。
Step 2:robots.txt 里声明 sitemap
public/robots.txt:
User-agent: *
Allow: /
Sitemap: https://yoursite.com/sitemap-index.xml
有 index 用 index 的 URL,没有就用 sitemap.xml。多个 Sitemap: 行是允许的(每个分片都列,或只列 index)。rebuild 后 curl -s https://yoursite.com/robots.txt 必须能看到 Sitemap: 行。
Step 3:让 <lastmod> 带上真实信号
ping 端点既然死了,lastmod 现在就是告诉 Google “重抓这个” 的主要信号。要按文章取,别用 build 时间。
Astro 例子(astro.config.mjs 配 @astrojs/sitemap):
import sitemap from "@astrojs/sitemap";
export default defineConfig({
integrations: [
sitemap({
serialize(item) {
// 把每个 URL 映射回它对应文章的真实更新时间
item.lastmod = lastmodForUrl(item.url); // 你的 frontmatter updatedAt
item.changefreq = "weekly";
item.priority = 0.7;
return item;
},
}),
],
});
lastmod 从 frontmatter 的 updatedAt 取(文章没改过就退回 publishedAt)。别给每一条都盖上 new Date() 的 build 时间——Google 会把整齐划一的”全新”时间戳当噪声忽略掉。
Step 4:在 Search Console 里重新提交
search.google.com/search-console > 选属性 > 左边 Sitemaps。
Add a new sitemap:
https://yoursite.com/sitemap-index.xml
Submit
活跃属性几分钟就读,刚开站的久一点。如果已经有一个 sitemap 显示 Couldn't fetch 或 “Last read” 很老:
- 从列表里 remove 掉。
- 用同一个 URL 重新 add。
- remove + re-add 会强制重抓一次。
Step 5(可选):用 API 自动化 Search Console 重提交
老 ping 的受支持替代品是 Search Console API 的 sitemaps.submit 方法(scope 为 https://www.googleapis.com/auth/webmasters)。它是一个 PUT:
https://www.googleapis.com/webmasters/v3/sites/{SITE_URL}/sitemaps/{FEEDPATH}
其中 {FEEDPATH} 是 URL 编码后的 sitemap URL。调用成功返回空的 200 body。用一个 service-account token 把它接进部署步骤,就能每次发版自动把 sitemap 重新排队——这才是正规的”自动重提交”路径,不是去 curl /ping。
Step 6:用 IndexNow 通知 Bing 和其他引擎
Bing、Yandex、Seznam、Naver、Yep 都不再接受 sitemap ping,它们用 IndexNow。你在 https://yoursite.com/<key>.txt 放一个 key 文件(key 为 8-128 位字符,可用 a-z、A-Z、0-9 和 -,是文件唯一的内容——它故意公开,好让引擎验证所有权),然后 POST 变更过的 URL:
curl -s -X POST "https://api.indexnow.org/indexnow" \
-H "Content-Type: application/json; charset=utf-8" \
-d '{
"host": "yoursite.com",
"key": "YOUR_KEY",
"keyLocation": "https://yoursite.com/YOUR_KEY.txt",
"urlList": ["https://yoursite.com/articles/new-article-slug/"]
}'
单次最多 10,000 个 URL;返回 200 或 202 即已接受。注意:Google 不消费 IndexNow(截至 2026 年 6 月),所以这只加速 Bing/Yandex 等——Google 那边你还是靠 Step 3-5。本站已经把 IndexNow ping 做成了 postbuild 步骤(scripts/ping-indexnow.mjs),所以大多数部署这一步是自动的。
Step 7:重要页面用 URL Inspection 单页推进
特别重要的新页,在 Search Console 里单个推:
Search Console 顶部搜索框 > 粘贴 URL > Inspect
> "URL is not on Google" > Request Indexing
这一项有限速(每个属性大约一天就几次,负载高时 Google 还可能临时暂停队列),所以留给你最有价值的页面,别整批往里灌。
怎么确认修好了
curl -s https://yoursite.com/sitemap.xml | grep -c '<loc>'等于你期望的总数。- Search Console > Sitemaps > “Last read” 更新到了今天,状态是
Success。 - Sitemaps 报告里的 “Discovered URLs” 几天内攀向新总数。
site:yoursite.com/articles/new-article-slug约 3-7 天能搜到。- 新文章 1-2 周内出现在 Search Console > Pages > “Indexed” 里(取决于站点权重)。
长期预防
robots.txt永远声明 sitemap——一行的事,能消除一大类发现失败。- 输出准确的每 URL
<lastmod>;ping 没了之后,把它当作主要的”快来重抓”信号。 - 把 Search Console API 重提交和 IndexNow POST 自动化进部署管线,让”提交 sitemap”从手动发版清单里消失。
- 站点超过 50,000 个 URL(或 sitemap 接近 50 MB 未压缩)时,拆成 sitemap index 加分片——看 sitemap 5 万 URL 上限拆分。
- 每周看一眼 Search Console 的 Pages 报告;发现停滞或突然掉是早期预警。
常见坑
- curl
google.com/ping?sitemap=...或bing.com/ping?sitemap=...还以为生效了——现在都 404/410,啥都没做。 - 提交 sitemap URL 之前不确认它返回
200;404 的话提交会静默失败。 - 在 sitemap 里列被
robots.txt屏蔽的 URL——Search Console 会报Submitted URL blocked by robots.txt。 - 给每条
<lastmod>都盖 build 时间——Google 会忽略整齐划一的”全新”时间戳。 - sitemap 里混
http://和https://(或www/非www);选定 canonical 主机用到底。
FAQ
Q:我把部署里的 curl ping 删了——拿什么替代?
A:触发 Google 这件事没有替代品了,这个能力本身没了。Google 现在靠 <lastmod> 加 Search Console 提交来安排重抓。想自动重提交就用 Search Console API 的 sitemaps.submit,Bing/Yandex 等用 IndexNow 覆盖。
Q:重新提交 sitemap 会强制 Google 索引这些页面吗? A:不会。它只是把 sitemap 重新排进 Googlebot 下一轮抓取,并重新发现新增或变更的 URL。是否索引还取决于页面质量和站点权重。
Q:新 URL 多快会被索引? A:成功读取后通常 24-48 小时内被发现;完整索引一般 3-14 天,看权重。如果页面在 “Discovered - currently not indexed” 停得更久,看 discovered currently not indexed。
Q:sitemap 要包含图片吗? A:可选。图片 sitemap 扩展对图片搜索有用,但普通页面索引不必须。等核心 sitemap 稳定了再加。
相关阅读
- Sitemap 找不到
- Sitemap 提交了但没被索引
- Sitemap lastmod 永远是今天
- Sitemap 里有页面在 Search Console 里找不到
- Sitemap 引用了旧域名
- Robots meta 和 sitemap 冲突
标签: #content-site #运营 #排查