一次提交 URL,同时通知 Bing、Yandex、Naver 等多家海外搜索引擎来抓取,不用每个平台单独提交。 百度不支持 IndexNow,继续用百度自己的普通收录 API,两者并行不冲突。
一、IndexNow 是什么
IndexNow 是一个搜索引擎推送协议,你在网站上放一个密钥文件,然后通过 API 把新页面 URL 推送给 IndexNow,它会分发给所有支持该协议的搜索引擎。
支持的搜索引擎
| 搜索引擎 | 国家/地区 | 支持情况 |
|---|---|---|
| Bing(必应) | 全球 | ✅ 完全支持 |
| Yandex | 俄罗斯 | ✅ 完全支持 |
| Naver | 韩国 | ✅ 支持 |
| Seznam | 捷克 | ✅ 支持 |
| Yep | 全球(隐私搜索引擎) | ✅ 支持 |
| Mojek | 波兰 | ✅ 支持 |
| 百度 | 中国大陆 | ❌ 不支持 |
工作原理
- 在网站根目录放一个密钥验证文件。
- 通过 API POST 提交 URL 列表,带上密钥。
- 搜索引擎后端访问你的密钥文件验证所有权。
- 验证通过后,搜索引擎安排爬虫来抓取页面。
二、和百度推送的区别
| 对比项 | 百度普通收录 | IndexNow |
|---|---|---|
| 推送对象 | 百度 | Bing / Yandex / Naver 等 |
| 接口地址 | data.zz.baidu.com |
api.indexnow.org/indexnow |
| 推送方式 | POST text/plain |
POST application/json |
| 所有权验证 | 不需要,用 token | 需要在根目录放密钥文件 |
| 单次 URL 数 | 每日有额度 | 单次最多 100 条 |
| 限制 | 每日额度 | 频率过高返回 429 |
三、密钥文件准备(关键步骤)
1. 生成密钥
去 https://www.indexnow.org/ 自动生成一个随机密钥,或者自己写一段 8~128 位的随机字符串(只允许大小写字母、数字、横线)。
示例:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
2. 创建密钥文件
在网站根目录新建一个 txt 文件,文件名就是密钥,例如:
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.txt
文件内容只写密钥本身,不要多空格、换行、回车:
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
3. 验证密钥文件
浏览器访问:
https://你的域名/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6.txt
必须满足:
- ✅ 裸文本直接显示密钥
- ✅ HTTP 状态码 200
- ✅ 不能 404 / 403 / 301 跳转
- ✅ 海外 IP 也能访问(国内能打开 ≠ 海外 Bing 爬虫能打开)
常见坑
- 密钥区分大小写,文件名大小写错一个字符就失败。
- 文件编码必须 UTF-8 无 BOM。
- 文件内容不能有多余的换行和空格。
- 国内服务器如果有 WAF / 云锁 / 安全组拦截了海外 IP,搜索引擎后端访问不到这个 txt,会返回 403。
四、批量推送脚本(通用版)
新建一个 PHP 文件,放到网站根目录,例如 push.php:
<?php
// ===== 配置区,改成你自己的 =====
$host = "你的域名.com";
$key = "你的密钥";
$keyLocation = "https://你的域名.com/你的密钥.txt";
// 要推送的 URL 列表,单次最多 100 条
$urlList = [
"https://你的域名.com/post-1.html",
"https://你的域名.com/post-2.html",
"https://你的域名.com/post-3.html",
// 继续添加,不要超过 100 条
];
// ===== 以下代码不用改 =====
$postData = json_encode([
"host" => $host,
"key" => $key,
"keyLocation" => $keyLocation,
"urlList" => $urlList,
], JSON_UNESCAPED_SLASHES);
$opts = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json; charset=utf-8\r\n",
'content' => $postData,
'timeout' => 30,
],
];
$context = stream_context_create($opts);
$result = file_get_contents('https://api.indexnow.org/indexnow', false, $context);
$responseHeaders = $http_response_header;
echo "推送数量:" . count($urlList) . " 条<br>";
echo "返回内容:" . var_export($result, true) . "<br>";
echo "<pre>响应头:";
print_r($responseHeaders);
echo "</pre>";
?>
使用方法
- 把上面代码保存为
push.php,上传到网站根目录。 - 修改配置区的
$host、$key、$keyLocation。 - 把要推送的 URL 填入
$urlList数组,单次不要超过 100 条。 - 浏览器访问
https://你的域名.com/push.php。
判断是否成功
看响应头里的状态码:
- HTTP 200 OK +
Content-Length: 0= ✅ 提交成功,响应体为空是正常现象。 - 如果看到
X-MSEdge-Ref开头的响应头,说明请求已经到了微软 Bing 的服务器。
五、自动从数据库读 URL 批量推送(适合 BBS / CMS)
如果你的网站有数据库,可以让脚本自动读取最新文章 URL,不用手动复制粘贴。
以 SQLite 数据库为例:
<?php
$host = "你的域名.com";
$key = "你的密钥";
$keyLocation = "https://你的域名.com/你的密钥.txt";
// 连接数据库,读取最新文章
$dbFile = __DIR__ . '/site.db';
$db = new PDO("sqlite:{$dbFile}");
$stmt = $db->query("SELECT id FROM article ORDER BY create_time DESC LIMIT 100");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$urls = [];
foreach ($rows as $r) {
$urls[] = "https://你的域名.com/article-{$r['id']}.html";
}
// 推送
$postData = json_encode([
"host" => $host,
"key" => $key,
"keyLocation" => $keyLocation,
"urlList" => $urls,
], JSON_UNESCAPED_SLASHES);
$opts = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json; charset=utf-8\r\n",
'content' => $postData,
'timeout' => 30,
],
];
$context = stream_context_create($opts);
$result = file_get_contents('https://api.indexnow.org/indexnow', false, $context);
echo "推送数量:" . count($urls) . " 条<br>";
echo "返回结果:" . $result;
?>
MySQL 数据库的话,把 PDO 连接串改成 MySQL 的即可,SQL 查询语句对应修改。
六、WordPress 自动推送(functions.php 钩子)
如果你用的是 WordPress,可以把下面代码加到当前主题的 functions.php,实现发布 / 更新文章时自动推送,以后新增文章不用手动跑脚本:
// IndexNow 自动提交
add_action('save_post', function ($post_id) {
if (wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) return;
if (get_post_type($post_id) !== 'post') return;
if (get_post_status($post_id) !== 'publish') return;
$url = get_permalink($post_id);
$host = "你的域名.com";
$key = "你的密钥";
$keyLocation = "https://你的域名.com/你的密钥.txt";
$postData = json_encode([
"host" => $host,
"key" => $key,
"keyLocation" => $keyLocation,
"urlList" => [$url],
], JSON_UNESCAPED_SLASHES);
$opts = [
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/json; charset=utf-8\r\n",
'content' => $postData,
'timeout' => 15,
],
];
$context = stream_context_create($opts);
@file_get_contents('https://api.indexnow.org/indexnow', false, $context);
}, 10, 1);
注意:这个钩子只管新增 / 更新文章,存量历史文章仍然需要用第四节的批量脚本一次性推送。
七、接口返回码说明
| HTTP 状态码 | 含义 | 排查方向 |
|---|---|---|
| 200 OK | ✅ 提交成功 | 响应体为空是正常的 |
| 400 Bad Request | ❌ 请求格式错误 | JSON 格式不对、URL 非法 |
| 403 Forbidden | ❌ 密钥校验失败 | 搜索引擎访问不到你的 txt 文件,或文件内容不对 |
| 422 Unprocessable Entity | ❌ URL 域名不匹配 | urlList 里的域名和 host 字段不一致 |
| 429 Too Many Requests | ❌ 请求过多 | 频率太高,隔几分钟再试 |
八、常见问题排查
1. 访问密钥 txt 返回 404
- 检查文件名是否和密钥完全一致(大小写敏感)。
- 检查文件是否在网站根目录。
- 检查 Nginx / Apache 伪静态规则是否拦截了 .txt 文件。
2. 提交返回 403
- 国内浏览器能打开 txt,但海外 Bing 爬虫打不开。
- 检查服务器防火墙 / 安全组是否限制了海外 IP。
- 检查 CDN / WAF 是否拦截了海外请求。
- 用海外代理访问你的 txt,确认海外可访问。
3. 提交返回 400
- JSON 格式错误(少括号、引号没闭合)。
urlList为空。- URL 里带了 markdown 链接标记,要填纯 URL。
4. PHP 脚本访问报 500
- 检查
php.ini的allow_url_fopen是否开启(必须 On)。 - 检查
disable_functions是否禁用了file_get_contents。 - 看 PHP 错误日志定位。
5. 脚本返回空、没有响应头
- 服务器出站网络无法访问
api.indexnow.org,国内服务器常见。 - 可以尝试用 CDN / 海外中转服务器跑脚本。
九、注意事项
- 单次最多提交 100 条 URL,超过就分批。
- 不要反复推送未修改的旧 URL,不会加速收录,反而可能被判定为垃圾提交。
- 批量推送脚本用完就删,不要长期留在公网,防止别人恶意调用触发 429 限流。
- 如果必须保留脚本,加访问密码,只允许自己访问。
- IndexNow 只推海外搜索引擎,百度继续用自己的普通收录 API,两套并行。
- 提交成功只是通知搜索引擎来抓取,不等于立刻收录,收录还要看页面质量和网站权重。
十、快速上手清单
- [ ] 生成密钥,根目录放
{密钥}.txt文件 - [ ] 浏览器访问 txt 文件,确认返回 200、裸文本显示密钥
- [ ] (可选)确认海外 IP 也能访问这个 txt
- [ ] 复制第四节的批量脚本,改成自己的域名和密钥
- [ ] 填入要推送的 URL(≤100 条),访问脚本提交
- [ ] 看返回 200 即成功
- [ ] (可选)WordPress 用户加第六节的 functions.php 钩子,实现自动推送
- [ ] 用完删除批量脚本
- [ ] 百度继续用原来的推送方式,互不影响