GitHub Actions 实现博客自动推送 IndexNow · 搜索引擎快速收录教程

作为静态博客(比如Hexo/Hugo搭建的博客或静态网站)博主,你一定遇到过发布新文章后,搜索引擎迟迟不收录的问题。手动提交链接到搜索引擎不仅繁琐,还容易遗漏;而IndexNow协议(由Bing/Yandex等搜索引擎推出)能让搜索引擎快速发现并收录你的网站内容,结合GitHub Actions的自动化能力,可实现博客发布即自动推送多搜索引擎,彻底解放双手。

除了提升搜索引擎收录,给博客增添节日氛围感也是站长的小小心愿,我之前写了《博客美化3D JS/CSS 灯笼》一文,纯 JS+CSS 实现,无第三方库依赖,Hexo/Hugo/WordPress等所有博客均可一键集成,新年新内容+新年新特效,氛围感拉满。

本文将从核心概念入手,一步步教你用GitHub Actions实现博客内容自动推送到Bing IndexNow,兼顾实用性和可扩展性。

注意:如果博客无Github仓库,可以创建一个空仓库,再按照本文步骤配置GitHub Actions(无需博客代码)。
本文以用Github+Vercel+Hexo搭建的博客为例,其他静态博客搭建方式类似。

如果你在内网搭建了个人博客,想让外网的朋友也能访问,哪怕没有公网 IP,也可以参考我写的《使用贝锐花生壳内网穿透,实现在无外网 IP 访问内网服务》一文,轻松实现内网博客的外网发布与访问,再配合本文的自动收录,内网博客也能快速被搜索引擎抓取。

核心概念速览

GitHub Actions与CI/CD

CI/CD(持续集成/持续部署)是DevOps的核心实践,而GitHub Actions是GitHub内置的CI/CD工具,无需额外服务器,只需在仓库中编写yml格式的工作流文件,就能实现代码推送、定时任务等触发的自动化操作(比如博客构建、部署、搜索引擎推送)。

IndexNow:搜索引擎快速收录的利器

IndexNow是一套开放的协议,核心作用是:网站内容更新后,主动通知搜索引擎,搜索引擎会快速抓取并更新索引,相比传统的sitemap定期抓取,收录效率提升数倍。

  • 核心优势:免费、实时、跨搜索引擎(支持Bing、Yandex等);
  • 工作原理
    1. 生成唯一API Key,并将Key以{key}.txt的形式放在网站根目录(验证网站归属);
    2. 向IndexNow API提交更新的URL列表,附带API Key和网站域名;
    3. 搜索引擎验证Key合法性后,立即抓取并收录URL。

实操步骤:GitHub Actions自动推送IndexNow

前期准备

  1. 获取IndexNow API Key
    访问Bing IndexNow官网,点击Generate API Key生成唯一Key(比如0a1818e0fea342e09e060743f4da9b44)。

生成API Key截图
生成API Key截图

  1. 验证网站归属
    创建一个名为{你的API Key}.txt的文件(比如0a1818e0fea342e09e060743f4da9b44.txt),文件内容仅需填写你的API Key,然后将该文件上传到博客根目录(比如https://jackie.openenet.cn/0a1818e0fea342e09e060743f4da9b44.txt),确保能通过浏览器访问。
  2. 准备Sitemap文件
    确保博客有可访问的Sitemap文件(支持xmltxt格式):
    • sitemap.txt:每行一个完整URL(比如https://jackie.openenet.cn/xxx.html);
    • sitemap.xml:符合标准XML格式的站点地图(下文代码已适配两种格式)。

想要让你的博客访问速度更快、搜索引擎抓取更稳定,一款稳定、高性价比的云服务器是关键。我自己的部分服务就是部署在雨云云服务器,国内高防节点访问延迟低,香港三线节点运行稳定,静态资源加载速度快,性价比拉满,支持一键部署 Hexo、Hugo、WordPress 等主流博客程序(基于K8S),还提供免费的SSL证书,一站式搞定博客部署全流程。新人通过我的专属推广链接注册,可免费获得首月5折+博主不定期补给福利,哪怕是学生党也能轻松负担!
雨云服务器

配置GitHub Secrets

硬编码API Key会有泄露风险,需将敏感信息存到GitHub仓库的Secrets中:

  1. 打开博客仓库 → 「Settings」→ 「Secrets and variables」→ 「Actions」→ 「New repository secret」;
  2. 添加以下两个机密:
    • 名称:INDEXNOW_KEY,值:你的IndexNow API Key(比如0a1818e0fea342e09e060743f4da9b44);
    • 名称:INDEXNOW_KEY_LOCATION,值:Key文件的访问地址(比如https://jackie.openenet.cn/0a1818e0fea342e09e060743f4da9b44.txt);
    • 可选补充:INDEXNOW_HOST(博客域名,比如jackie.openenet.cn)、SITEMAP_URL(Sitemap地址,比如https://jackie.openenet.cn/sitemap.txt)。

机密配置截图
机密配置截图

编写GitHub Actions工作流文件

在博客仓库根目录创建.github/workflows/indexnow.yml文件,以下是完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# 工作流名称:提交博客URL到Bing IndexNow
name: Submit Blog URLs to Bing IndexNow

# 触发条件:
# 1. 推送到main分支(博客发布/更新时);
# 2. 每天凌晨1点定时推送(补漏);
# 3. 手动触发(应急使用)。
on:
push:
branches: ["main"]
# 可选:仅当博客内容文件变更时触发(减少无效执行)
paths:
- "content/**"
- "posts/**"
- "source/**"
schedule:
- cron: '0 1 * * *' # UTC时间,对应北京时间9点
workflow_dispatch: # 手动触发开关

# 权限配置:仅读取仓库内容(最小权限原则)
permissions:
contents: read

# 定义任务
jobs:
submit-to-indexnow:
runs-on: ubuntu-latest # 使用Ubuntu最新版运行环境
steps:
# 步骤1:安装依赖(jq用于处理JSON,curl用于请求,xmlstarlet用于解析xml sitemap)
- name: Install dependencies
run: |
sudo apt-get update && sudo apt-get install -y jq curl xmlstarlet

# 步骤2:延迟执行(仅push触发时)- 等待博客部署完成(避免推送未生效的URL)
- name: Wait for blog deployment (only on push)
if: github.event_name == 'push'
run: sleep 60 # 延迟1分钟,可根据博客部署耗时调整

# 步骤3:核心逻辑:获取Sitemap并推送到IndexNow
- name: Fetch sitemap and submit to Bing IndexNow
env:
# 从GitHub Secrets读取敏感信息(避免硬编码)
INDEXNOW_KEY: ${{ secrets.INDEXNOW_KEY }}
INDEXNOW_KEY_LOCATION: ${{ secrets.INDEXNOW_KEY_LOCATION }}
INDEXNOW_HOST: ${{ secrets.INDEXNOW_HOST || 'jackie.openenet.cn' }}
SITEMAP_URL: ${{ secrets.SITEMAP_URL || 'https://jackie.openenet.cn/sitemap.txt' }}
run: |
# ========== 1. 参数校验 ==========
echo "=== 校验配置参数 ==="
if [ -z "$INDEXNOW_KEY" ] || [ -z "$INDEXNOW_KEY_LOCATION" ] || [ -z "$INDEXNOW_HOST" ] || [ -z "$SITEMAP_URL" ]; then
echo "❌ 错误:缺少必要配置参数,请检查GitHub Secrets"
exit 1
fi
echo "✅ 配置参数校验通过"
echo "博客域名:$INDEXNOW_HOST"
echo "Sitemap地址:$SITEMAP_URL"

# ========== 2. 下载并解析Sitemap ==========
echo -e "\n=== 下载并解析Sitemap ==="
# 下载Sitemap文件
if ! curl -s -o sitemap.tmp "$SITEMAP_URL"; then
echo "❌ 错误:无法下载Sitemap文件($SITEMAP_URL)"
exit 1
fi

# 区分Sitemap格式(txt/xml)并提取URL
if [[ "$SITEMAP_URL" =~ \.xml$ ]]; then
# 解析xml格式Sitemap
xmlstarlet sel -t -v "//url/loc" sitemap.tmp | grep "^https://$INDEXNOW_HOST/" | sort -u > valid_urls.txt
else
# 解析txt格式Sitemap(每行一个URL)
grep -v '^$' sitemap.tmp | sort -u | grep "^https://$INDEXNOW_HOST/" > valid_urls.txt
fi

# 检查有效URL数量
if [ ! -s valid_urls.txt ]; then
echo "❌ 错误:未提取到有效URL(请检查Sitemap格式和域名)"
exit 1
fi
VALID_URL_COUNT=$(wc -l < valid_urls.txt)
echo "✅ 提取到有效URL数量:$VALID_URL_COUNT"
# 打印前5个URL(便于调试)
echo "前5个有效URL:"
head -5 valid_urls.txt

# ========== 3. 构造IndexNow API请求数据 ==========
echo -e "\n=== 构造API请求数据 ==="
# 将URL列表转为JSON数组
URL_LIST=$(jq -R -s -c 'split("\n") | map(select(length > 0))' valid_urls.txt)
# 构造完整JSON请求体
JSON_DATA=$(jq -n \
--arg host "$INDEXNOW_HOST" \
--arg key "$INDEXNOW_KEY" \
--arg keyLocation "$INDEXNOW_KEY_LOCATION" \
--argjson urlList "$URL_LIST" \
'{host: $host, key: $key, keyLocation: $keyLocation, urlList: $urlList}')
echo "✅ 请求数据构造完成(JSON):"
echo "$JSON_DATA" | jq . # 格式化输出JSON(便于调试)

# ========== 4. 提交到Bing IndexNow API ==========
echo -e "\n=== 提交到Bing IndexNow API ==="
# 发送POST请求,捕获状态码和响应内容
RESPONSE=$(curl -s -w "\nHTTP_STATUS:%{http_code}" -X POST \
-H "Content-Type: application/json" \
-d "$JSON_DATA" \
"https://www.bing.com/indexnow?url=https://$INDEXNOW_HOST&key=$INDEXNOW_KEY")

# 分离响应内容和HTTP状态码
HTTP_STATUS=$(echo "$RESPONSE" | grep -oP 'HTTP_STATUS:\K\d+' | tail -1)
API_RESPONSE=$(echo "$RESPONSE" | sed '/HTTP_STATUS:/d')

# ========== 5. 结果判断与日志 ==========
echo -e "\n=== 提交结果 ==="
echo "HTTP状态码:$HTTP_STATUS"
echo "API响应内容:$API_RESPONSE"

# 成功条件:状态码200(成功)/202(接受待处理),或响应包含success/jobId
if [[ $HTTP_STATUS =~ ^20[02]$ ]] || echo "$API_RESPONSE" | grep -qE '"success":true|"jobId"'; then
echo -e "\n✅ 成功:$VALID_URL_COUNT 个URL已提交到Bing IndexNow"
else
echo -e "\n❌ 失败:提交失败(状态码:$HTTP_STATUS)"
exit 1
fi

编写工作流文件截图
编写工作流文件截图

测试与验证

  1. 手动触发工作流
    仓库 → 「Actions」→ 找到「Submit Blog URLs to Bing IndexNow」→ 「Run workflow」→ 点击「Run workflow」,查看运行日志(绿色对勾表示成功);

手动触发工作流截图
手动触发工作流截图

  1. 验证推送结果
    登录Bing网站管理员工具,在「IndexNow」板块可查看提交记录和处理状态。

常见问题与优化建议

常见问题排查

  1. Key验证失败:检查{key}.txt文件是否能访问、文件内容是否仅为Key、Key是否与Secrets中一致;
  2. Sitemap解析失败:确认Sitemap地址可访问、URL格式为完整的https://开头、域名与配置的INDEXNOW_HOST一致;
  3. HTTP状态码400/403
    • 400:JSON格式错误(检查URL列表是否为空);
    • 403:Key验证失败(重新检查Key文件);
    • 429:请求频率超限。

优化建议

  1. 限制推送频率:在on.push.paths中指定仅博客内容文件变更时触发,减少无效执行;
  2. 拆分大批量URL:如果URL数量超过1000,可在代码中拆分批次提交;
  3. 多搜索引擎适配:IndexNow协议支持多引擎,只需将API地址替换为对应引擎(如Yandex:https://yandex.com/indexnow);

注意:在任意支持IndexNow的搜索引擎提交后,其它搜索引擎也可自动收录。

  1. 增加失败重试:添加actions/github-script实现失败自动重试(最多3次)。

总结

通过GitHub Actions + IndexNow的组合,你实现了「博客内容更新→自动推送→搜索引擎快速收录」的全自动化流程,核心优势:

  1. 无需手动操作,彻底解放双手;
  2. 避免硬编码敏感信息,符合安全最佳实践;
  3. 适配多种Sitemap格式,兼容性强;
  4. 详细的日志输出,便于故障排查。

这套思路也可延伸到其他自动化场景(比如博客自动部署、图片压缩、链接检查),CI/CD的核心价值就是让重复的工作自动化,让你专注于内容创作而非繁琐的运维操作。

⚠️ 申明:本文内容由作者结合实际实操经验撰写,部分技术细节(如代码解析,代码细节)借助 AIGC 工具辅助整理,所有内容均经过作者亲自验证,确保准确可用。

【站长专属福利】
个人博客搭建、前端特效部署,一款稳定、高性价比的云服务器都是站长的刚需。我自己用了 1 年多的雨云,国内节点访问稳定,支持一键部署各类博客程序、开发环境(基于K8S),性价比极高,还提供免费的 SSL 证书,一站式搞定博客部署全流程。新人通过我的专属推广链接注册,除了官方新人福利,还能额外解锁首月5折+博主不定期补给福利,有需要的朋友可以看看。
雨云服务器
注:本文所有代码均为开源免费分享,无任何商业合作,云服务器推荐仅为我本人真实使用体验,觉得确实能解决新手站长的痛点,推广链接可获得平台官方的少量奖励,不会给你带来任何额外成本,感谢你的支持!

🛠️ 博主专属配套工具 & 福利

⚠️ 风险提示:加密货币投资存在较高市场风险,需严格遵守所在地区法律法规,以下内容仅做工具知识分享,不构成任何投资建议。
请我喝杯咖啡吧!
Jackie 比特币 比特币
Jackie 以太坊 以太坊
Jackie 波场 波场
Jackie 阿尔比垂姆 阿尔比垂姆
Jackie 币安智能链 币安智能链
欢迎关注我的其它发布渠道