报错是这么冒出来的。批量提交 500 条 URL 时接口返回 422 Unprocessable Entity,单条提交却正常。URL 列表来自数据库导出,中间有几条带空格和中文。试过换 key,仍然 422。

中间走过弯路,把「单次提交数量超过接口上限」当成主因,改完现象没变。

把日志和配置对完,能解释这个现象的基本就这几处。URL 里有未编码的空格或中文,JSON 结构合法但内容无法解析。也可能是urlList 里混入了非 http 协议的地址。

另外,host 字段与实际 URL 的主机名不一致。

先用单条验证 key 是否有效

curl -s -o /dev/null -w "%{http_code}\n" -X POST https://api.indexnow.org/indexnow -H 'Content-Type: application/json' -d '{"host":"www.example.com","key":"8f3a2c1d","urlList":["https://www.example.com/post/1/"]}'

再往下检查 URL 列表里的异常字符

python -c "import json;[print(u) for u in json.load(open('urls.json'))['urlList'] if ' ' in u or not u.startswith('https://')]"

然后按 10000 条分批提交

split -l 10000 urls.txt batch_

剩下的就是用编码后的地址重试

python -c "import json,urllib.parse;d=json.load(open('urls.json'));d['urlList']=[urllib.parse.quote(u,safe=':/') for u in d['urlList']];json.dump(d,open('urls2.json','w'))"

手上没有现成的复现脚本,就照着线上请求手工拼了一个。

别只看报错消失,验证要多做一步。清理异常地址并分批后,所有批次都返回 200,Bing 的抓取日志里出现对应 URL 的请求。

422 基本都是内容问题不是鉴权问题,先把 urlList 逐条打印出来看,比反复换 key 有效。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189