内容发出去还在等收录:IndexNow 协议与 Bing Webmaster 的即时提交接入规范

2026-09-26 01:16:07 1 次浏览
SEOBing WebmasterIndexNowsitemap独立站

适用读者:负责外贸独立站的技术与 SEO 同学,站点跑在 .NET 上,Bing 带来的海外流量不能忽视,想搞清楚 IndexNow(即时索引协议)到底怎么接、接了会不会被判定滥用。

去年 11 月接手一个外贸独立站的技术支持,站点日均上新 30 个 SKU 页,sitemap 每天自动生成一次,但 Bing 的收录中位延迟长期卡在 7 到 14 天。运营负责人老周在周会上原话是:"产品页发出去两个星期,客户拿型号词去搜,连影子都没有,询盘全被同行截走了。"我们把发布链路改造成 IndexNow 推送加 Bing Webmaster API 兜底,今年 3 月拉了四周数据,收录中位延迟降到 26 小时。整个改造后端代码不到 150 行,难点不在写代码,而在协议细节和提交频次的拿捏。这篇文章把接入规范逐条拆开讲。

sitemap 为什么等不来快收录

sitemap 本质上是一份被动提交的 URL 清单。搜索引擎的抓取调度器会周期性读取它,但什么时候真正派爬虫来抓,完全取决于对方的抓取预算(Crawl Budget)分配。对中小体量的独立站,Bing 分配的抓取频次很保守,新页面往往要排好几轮队列。

通知铃即时推送 URL 到搜索引擎

这里有个容易被忽略的时间结构:sitemap 的更新周期加上调度器的轮询周期,再算上页面质量评估的排队时间,叠加起来就是那 7 到 14 天。你多发一篇产品页,这个延迟不会缩短半分,因为 sitemap 模式下站点对收录时机的干预能力约等于零。

IndexNow 把这个模式倒过来了:页面发布的那一刻,站点主动把 URL 推给搜索引擎端点,爬虫会尽快来抓。一个推、一个拉,时效差距就是这么来的。

IndexNow 协议规范逐条解读

IndexNow 是微软 Bing 和 Yandex 在 2021 年联合发起的开放协议,后来 Naver、Seznam 也加入了。规范本身不长,但每条都有坑,逐条过一遍。

key 文件验证。你要先生成一个 8 到 32 位十六进制字符的 key(比如 a1b2c3d4e5f6),然后把它做成一个文本文件放在站点根目录:https://yourdomain.com/{key}.txt,文件内容就是这个 key 本身,不要带换行以外的任何多余字符。搜索引擎收到提交请求后,会回源拉这个文件,确认提交者真的控制这个域名。一个站点只需要一个 key,子域名可以共用,但协议要求 host 与 key 文件所在域名一致,跨域名提交会被拒。Linux 环境两行命令就能生成并落盘:

# 生成 32 位十六进制随机串作为 key
# openssl -hex 输出正好符合 8-32 字符的协议要求
KEY=$(openssl rand -hex 16)
# key 文件名和文件内容都必须与 key 完全一致
# printf 不带 \n,避免文件末尾换行导致校验差异
printf '%s' "$KEY" > "/var/www/site/$KEY.txt"
# 最后把 KEY 值记录到配置中心,提交端要用同一个值
echo "IndexNow key: $KEY"

提交方式。单条 URL 用 GET 就够,浏览器或 curl 直接访问即可:

https://api.indexnow.org/indexnow?url=https%3A%2F%2Fyourdomain.com%2Fp%2Fsku-123&key=你的key

批量提交用 POST,往 https://api.indexnow.org/IndexNow 发一个 JSON,host 填主域名,keyLocation 可以省略(默认就是根目录 key 文件),urlList 一次最多放 10000 条 URL,报文总大小不能超过 2MB。建议每批控制在 1000 条以内,引擎处理起来更快。api.indexnow.org 是公共端点,提交一次会分发给所有接入协议的搜索引擎;你也可以直接用各家的专属端点,比如 bing.com/indexnow。

响应码语义。这部分官方文档写得比较散,实测整理成表格:

状态码 含义 处理建议
200 OK URL 已收到并验证通过,进入抓取队列 正常,不用重试
202 Accepted 请求收到,key 尚未验证,稍后回源验证 key 文件 首次提交的正常现象,别当错误重发
400 Bad Request 报文格式不合法 检查 JSON 结构和 URL 编码
403 Forbidden key 文件校验失败,提交被判定无效 检查 key 文件内容与 URL 是否一致
422 Unprocessable Entity URL 不属于 key 文件所在域名 只提交本站 URL
429 Too Many Requests 提交过于频繁,触发限流 退避后降低频次

容易踩的规范细节。URL 必须经过 URL 编码;urlList 里不能混入其他域名的链接;key 文件如果被 CDN 缓存了旧内容,会导致 403,建议给 *.txt 这类路径在 CDN 上设置直通源站的缓存规则。我们在 12 月初就栽过一次,Cloudflare 把 key 文件缓存成了上一次部署的旧 key,提交全返 403,排查了一下午。

key 验证的机制拆解

这一节讲原理。IndexNow 的信任模型很朴素:它不搞账号体系,凭证只有一样:"你能控制某个路径下的某个文件"。引擎收到第一次提交时,会先回一个 202,同时异步去拉 keyLocation 指向的文件;拉到的内容与提交里声明的 key 一致,这个 host 才会被标记为已验证,后续提交直接走 200 的快车道。

sequenceDiagram
    participant S as 站点(.NET 8 后台服务)
    participant E as api.indexnow.org
    participant C as 搜索引擎抓取调度器
    S->>E: POST urlList + key
    E-->>S: 202 Accepted(key 未验证)
    E->>S: GET /{key}.txt 回源验证
    S-->>E: 返回 key 原文
    E->>E: 比对一致,标记 host 已验证
    E->>C: 把 URL 注入高优先级抓取队列
    C->>S: 爬虫抓取产品页

验证通过之后,之前 202 状态下积压的提交不会丢,会一并入队。这个设计的好处是接入成本极低——不用注册账号、不用 API token——代价是 key 一旦泄露,任何人都能替你提交垃圾 URL 污染你的站点配额。所以 key 文件路径虽然公开,也别在公开仓库里到处贴。

整个推送链路放一张全景图:

flowchart LR
    A[商品发布事件] --> B[领域事件: ProductPublished]
    B --> C[后台推送服务]
    C --> D{提交方式判断}
    D -- 单条 --> E[GET 端点提交]
    D -- 攒批 --> F[POST 批量提交<br/>urlList 最多 10000 条]
    E --> G[200/202 响应]
    F --> G
    G -- 403/422/429 --> H[记日志+退避重试]
    G -- 200 --> I[等待爬虫抓取]
    I --> J[Bing Webmaster 后台核对收录状态]
    J -- 超过 72 小时未抓 --> K[API 兜底再提交一次]

.NET 8 后台发布事件触发提交

环境说明:.NET 8 Web API 项目,HttpClient 走 IHttpClientFactory 注册,推送逻辑放在一个继承 BackgroundService 的常驻服务里,消费内存通道里的发布事件。依赖只有框架自带的 System.Text.Json,不引第三方包。

// IndexNow 推送服务:消费商品发布事件,攒批后提交
// 放在 BackgroundService 里跑,失败不影响商品发布主流程
public sealed class IndexNowPushService : BackgroundService
{
    // 批量上限 10000,实际攒 500 条就发,避免单批过大被限流
    // 日均 30 条的量级攒大批纯属浪费等待时间
    private const int BatchSize = 500;
    private readonly ChannelReader<PublishedEvent> _reader;
    private readonly IHttpClientFactory _httpFactory;
    private readonly ILogger<IndexNowPushService> _logger;

    public IndexNowPushService(
        Channel<PublishedEvent> channel,
        IHttpClientFactory httpFactory,
        ILogger<IndexNowPushService> logger)
    {
        // 从 DI 容器取通道读取端,事件由发布流程写入
        // 构造函数注入即可,不需要手动管理生命周期
        _reader = channel.Reader;
        _httpFactory = httpFactory;
        _logger = logger;
    }

    // ExecuteAsync 随宿主启动,宿主关闭时通过取消令牌优雅退出
    protected override async Task ExecuteAsync(CancellationToken ct)
    {
        // 用一个缓冲区把短时间内的发布攒成一批
        var batch = new List<string>(BatchSize);

        // WaitToReadAsync 无事件时挂起等待,不空转占 CPU
        while (await _reader.WaitToReadAsync(ct))
        {
            while (_reader.TryRead(out var evt))
            {
                // 只推标准产品页,营销落地页走另一条链路
                // URL 要完整带上 https 前缀,相对路径会被判 400
                batch.Add($"https://shop.example.com/p/{evt.Sku}");
                // 攒满一批立刻发出,不等下一个时间窗口
                if (batch.Count >= BatchSize)
                {
                    await PushAsync(batch, ct);
                    // 提交后清空缓冲区,开始攒下一批
                    batch.Clear();
                }
            }
            // 批未攒满也要发,否则低峰期 URL 会滞留
            // 窗口期结束就落一次盘,保证准实时语义
            if (batch.Count > 0)
            {
                await PushAsync(batch, ct);
                batch.Clear();
            }
        }
    }

    private async Task PushAsync(List<string> urls, CancellationToken ct)
    {
        // 按协议组装批量报文,host 必须与 key 文件所在域名一致
        var payload = new
        {
            host = "shop.example.com",
            key = "a1b2c3d4e5f60718",
            urlList = urls
        };
        // 命名客户端在 Program.cs 里统一配置了 10 秒超时
        var client = _httpFactory.CreateClient("indexnow");
        var resp = await client.PostAsJsonAsync(
            "https://api.indexnow.org/IndexNow", payload, ct);

        // 200 与 202 都算提交成功,区别只在 key 是否已验证过
        if (resp.StatusCode is HttpStatusCode.OK or HttpStatusCode.Accepted)
            return;

        // 429 说明触发限流,退避 10 分钟再走重试队列
        // 重试任务交给独立的 Hangfire 队列,这里只负责记录
        if (resp.StatusCode == HttpStatusCode.TooManyRequests)
            _logger.LogWarning("IndexNow 限流,{Count} 条 URL 进入退避队列", urls.Count);
        else
            // 403/422 多半是 key 文件或域名不匹配,直接告警人工介入
            // 这两类错误重试无意义,先修配置再补交
            _logger.LogError("IndexNow 提交失败 {Code},批次 {Count} 条",
                (int)resp.StatusCode, urls.Count);
    }
}

两个实现细节值得说。一是 BatchSize 定在 500 而不是上限 10000,是因为日均 30 条的量根本攒不满大批,攒批窗口一长反而拖慢首条 URL 的时效,实测 5 分钟内的小批提交响应最快。二是不要在 HTTP 请求线程里同步等响应,推送失败不能阻塞商品发布主流程,这也是为什么放后台服务而不是发布接口里顺手调一下。

Bing Webmaster Tools 的 API 和 sitemap 怎么配合

IndexNow 负责增量,Bing Webmaster Tools(BWT)负责全量和可观测性,两条腿缺一不可。BWT 后台先把 sitemap 地址登记好,这是引擎做全量对账的基线;然后在 BWT 的 API 访问页生成一个 API Key,就能调用它的 URL Submission API,每天有单独的配额(普通站点每日数千条),和 IndexNow 的配额互相独立。

手段 定位 时效 适用场景
sitemap 全量清单,被动等待 天级到周级 兜底,保证不漏页
IndexNow 增量推送,事件驱动 小时级 新发布、内容更新的页面
BWT URL Submission API 手动/脚本补交 小时级 IndexNow 异常时的兜底重试

这里要专门纠正一个流传很广的误解:Google 不支持 IndexNow。协议端点只会分发给接入的引擎(Bing、Yandex、Naver、Seznam),Google 的普通页面收录仍然依赖 sitemap 和 Google Search Console,它自家的 Indexing API 只对职位发布和直播视频开放。所以别指望接了 IndexNow,Google 那边的收录也跟着提速,那是两套体系。

Naver、Seznam、Yandex 共享同一个 key 文件和提交规范,独立站如果做韩国或东欧市场,用公共端点 api.indexnow.org 一次提交就能覆盖这几家,不需要逐家对接,这也是这个协议对中小团队最实惠的地方。

提交频次与滥用风险

协议免费开放,但搜索引擎对滥用毫不客气。官方给的边界是:只提交新增或内容有实质变化的 URL,重复提交没变化的链接、提交已经 404 的页面、用脚本高频轰炸端点,都会触发 429 限流,严重的会拉低整个域名的提交信任度,后续请求被长期降级。

我们自己定的内部基线:单条 URL 从发布到提交至少间隔一次内容变更;批提交每 5 分钟最多一轮;429 之后指数退避,10 分钟、20 分钟、40 分钟,三轮之后进人工队列。上线头两周我们有个bug,商品改一次库存也会触发发布事件,等于同一 URL 一天被推十几遍,Bing 直接回了 429,把事件去重逻辑加上之后才恢复。频次这件事,宁可保守。

误区澄清或趋势预判

两个常见误区先摆平。误区一是"提交了就会收录"——IndexNow 只解决"尽快被抓",抓完之后页面质量评估、去重、排名照旧走搜索引擎自己的流程,低质量页面照样不收。误区二是"key 文件越隐蔽越安全"——key 本来就是公开验证用的,真正的安全边界是别泄露到能被第三方替你提交的程度即可,过度包装没有意义。

再往趋势上看一眼,即时提交这件事对 GEO(Generative Engine Optimization,生成式引擎优化)也有间接价值。AI 爬虫(GPTBot、ClaudeBot 这类)的抓取频次普遍比传统爬虫低得多,新页面进入 AI 语料的窗口期更长;而 Bing 的索引同时是 ChatGPT 搜索引用的数据源之一,IndexNow 把页面送进 Bing 索引的速度提上来,等于顺带压缩了页面被 AI 引擎发现的时间。对以外贸询盘为生的独立站,这个时间差有时就是订单差。

参考与延伸

  • IndexNow 官方协议文档(key 规范、提交格式、响应码):https://www.indexnow.org/documentation
  • Bing Webmaster Tools 产品与功能入口:https://www.bing.com/webmasters/about
  • Bing Webmaster API 官方文档(URL Submission、sitemap 管理):https://learn.microsoft.com/en-us/bingwebmaster/

IndexNow、Bing Webmaster、收录提速、sitemap、独立站SEO、即时提交

🤖
本内容由 AI 辅助生成,经人工校对审核;部分素材、资料来源于公开网络,仅作个人观点分享与交流使用,无任何商业侵权意图。若内容、图片、文字涉及您的合法著作权、版权权益,请联系本人,核实后将第一时间删除、修改相关内容。