大版本更新
一口气全面统一博客样式,移除部分冗余导航页面,更专注内容展示。
不因虚度年华而悔恨,不因碌碌无为而羞愧
博客系列第9期。用 GitHub Actions 自动检测友链可达性、反链存在、主页截图,零服务器零运维,附触发方式详解。

友链多了之后总有个头疼的问题——对方悄悄撤了你的链接,或者站点直接挂了,你还蒙在鼓里。手动一个个点进去检查?四五十个友链,想想就累。
所以我搞了个自动化方案:每天定时检测友链状态,每 6 天自动截一张主页图,结果输出成一个 JSON,博客前端直接拉取展示。全程跑在 GitHub Actions 上,不用服务器,不用花钱。

| 项目 | 说明 |
|---|---|
| willow-god/check-flink | 友链状态检测核心(多线程延迟检测 + 反链检测) |
| thun888/Python-WebSite-Screenshot | Selenium 主页截图核心 |
| fqzlr/check-flink | 我的整合版(本文主角) |
| cfbed.sanyue.de | 图床 API 规范(截图上传用) |
| image.thum.io | 截图兜底服务(Selenium 挂了也不怕) |
把两个开源项目深度整合,最终架构长这样:
1博客 friends.json(唯一数据源)2 │3 ▼4┌─ check_links job(每天 2 次)─────────┐5│ 多线程请求每个友链 │6│ 统计:延迟 / 失败次数 / 反链存在 │7│ 输出 → result.json │8└────────────────────────────────────────┘9 │10 ▼11┌─ take_screenshots job(每 6 天)──────┐12│ 读取 result.json 中可达的友链 │13│ Selenium 截图 → 上传图床 │14│ 失败 → thum.io 兜底 │15│ 截图 URL 写回 result.json │16└────────────────────────────────────────┘17 │18 ▼19 Vercel 托管 result.json(CDN 加速)20 │21 ▼22 博客前端 fetch → 渲染友链卡片| 文件 | 作用 |
|---|---|
main.py | 状态检测 + 反链检测 + 增量合并 |
screenshot.py | Selenium 截图 + 图床上传 + thum.io 兜底 |
screenshot_runner.py | 截图入口,从 result.json 读取目标 |
inject.css | 截图时注入目标页面(隐藏滚动条/弹窗) |
.github/workflows/check_links.yml | 调度核心:定时 + 手动 + 条件触发 |
访问对方的友链页面,用正则提取所有真实的 <a href> 链接,解析主机名后跟自己的域名比对。
注意:只有真实超链接才算反链。如果对方只是在文章里提了一嘴你的域名(纯文本),不算。之前旧版用字符串匹配,结果把 5 个只是文字提及的站点误判成了有反链,后来重写了这块逻辑。
完整 8 步教程在 README,这里挑重点说。
把 fqzlr/check-flink fork 到你自己的 GitHub。
在仓库 Settings → Secrets and variables → Actions 里添加:
| Secret | 说明 | 示例 |
|---|---|---|
AUTHOR_URL | 你的域名(反链检测用) | fqzlr.com |
SOURCE_URL | 友链 JSON 地址 | https://fqzlr.com/friends.json |
IMG_API_URL | 图床上传 API | https://tu.xxx.com/api/upload |
IMG_API_TOKEN | 图床 API Token | your-token |
仓库 Settings → Actions → General → Workflow permissions → 选 Read and write permissions。
不然 workflow 没法把 result.json 提交回仓库。
你的博客需要暴露一个 JSON 接口,格式类似:
1[2 {3 "name": "番茄的博客",4 "link": "https://blog.example.com",5 "avatar": "https://...",6 "linkpage": "https://blog.example.com/friends"7 }8]其中 linkpage 是对方的友链页面地址(反链检测会访问这个页面)。
截图需要上传到图床。我用的是 Cloudflare-ImgBed(博客系列第 4 期讲过),API 兼容 cfbed.sanyue.de 规范。
Actions → Run workflow → task 选 both → target_link 留空 → 跑!
首次全量跑一遍,之后日常就自动了。
把仓库导入 Vercel,Output Directory 填 static,得到一个 CDN 地址。博客前端 fetch 这个地址的 result.json 就行。
这是我最满意的部分——灵活到可以只跑一个友链。
| 时间 | 执行内容 |
|---|---|
| 每天 01:00、13:00 | 仅状态检测(~1 分钟) |
| 每 6 天(1/7/13/19/25 号 01:30) | 状态检测 + 截图(~10 分钟) |
进 Actions → Run workflow,有两个参数:
task(选执行内容):
status_only:仅状态检测(默认)screenshots_only:仅截图(用上次检测数据)both:检测 + 截图target_link(只处理指定友链):
番茄 或 blog.example.com| 我想… | task | target_link |
|---|---|---|
| 日常看看谁挂了 | status_only | 留空 |
| 新加了个友链,检测一下 | status_only | 新友链名字 |
| 新加了个友链,检测+截图 | both | 新友链名字 |
| 截图太旧了,全部重截 | screenshots_only | 留空 |
| 全量跑一遍 | both | 留空 |
当你填了 target_link,只有匹配的友链会被重新检测/截图,其余友链保留上次结果。不会出现”只跑了一个友链,其他 46 个数据全没了”的情况。total_count 始终不变。
1Selenium 本地截图2 ├─ 成功 → 上传图床 → 图床 URL3 └─ 失败 → thum.io 在线截图(永远可用)所以即使 GitHub Actions 环境抽风装不上 Chrome,也不会出现白屏。
Selenium + Chrome 安装要 2-3 分钟,截完全部友链要 5-10 分钟。每天跑太浪费 Actions 配额(每月 2000 分钟),6 天一次刚刚好。
状态检测就轻量多了,纯 requests 请求,1 分钟跑完,所以每天 2 次不心疼。
友链配置只在博客侧维护(我的 friends.json),检测仓库自动读取。不用两边同步,加友链只需要在博客加一次。
整套方案跑下来零成本:GitHub Actions 免费额度足够,图床用 Cloudflare Workers 免费套餐,Vercel 也是免费的。
如果你也有几十号友链,与其隔三差五手动检查,不如让机器帮你盯着。
有问题欢迎评论区交流~
生成精美分享图或复制链接,与更多人分享本文。
最后更新于 ,距今已过 86 天
部分内容可能已过时