
为什么要在发布后进行审计
预检门控看到的是草稿,而审计看到的是上线站点的实际表现。插件会重写链接,编辑可能会将联盟营销重定向覆盖到干净的 URL 上,CDN 迁移也可能导致主机名变更。这些情况在草稿阶段都不存在,因此发布后的运行是发现这些问题的首要环节。
一个有用的审计在设计上应该是“无聊”的。它按计划运行,只写一行日志,除非触发异常否则保持静默。静默是目标。一个月的静默日志意味着工作正常,而不是处于空闲状态。
目前没有面向大众的官方 Google 反向链接检查器 API,因此团队通常调用第三方链接索引。这是我们的自有爬虫。Search Console 显示 Google 对您自身链接的视图,而审计是对它的补充而非替代。
作业运行位置
记录触发器。三种设置涵盖了大多数团队,每种设置都执行相同的调用。日志比触发器更重要,因为日期、URL 和使用的积分每次都必须记录在其中。
仓库的 GitHub Actions
如果站点从仓库构建,定时工作流带来的摩擦最小。作业位于代码旁边,密钥存储在仓库的密钥库中。下文的工作流文件是所需的最小配置。将其保留在仓库中,像其他代码一样进行审查,并锁定所依赖的 action 版本。
带有 cron 的普通服务器
已经拥有构建机器的团队可以在该机器上调度相同的命令。n8n 等工具可以通过“执行命令”步骤运行它们,或者 crontab 行可以直接运行它们。无论哪种方式,作业都应以能读取密钥且无其他权限的用户身份运行。
来自 CMS 的 webhook
某些 CMS 设置在文章上线时触发 webhook,该事件可以启动审计。检查随即在文章公开时运行。同时保留定时运行,因为单个 webhook 遗漏会导致文章未审计。
运行手册,按顺序
01发布时触发,30 天后再次触发
文章上线后立即运行一次,检查出站主机。一个月后再次运行,读取您站点的 refdomains,因为索引大约每月刷新一次,较早的读取将显示无新内容。
02首先调用免费概览
action=overview 以零成本返回站点的核心数据。将其存储为本次运行的基线行,并附带日期。
03仅在数据变化时拉取付费列表
如果概览数据与上月不同,调用 refdomains(2 积分)和 anchors(2 积分),并与存储的列表进行差异比较。
04写入一行日志
日期、文章 URL、调用次数、_credits 余额。提交到私有仓库的纯 CSV 文件即可。
05仅在异常时警报
HTTP 401、HTTP 402、上月有数据但本月结果为空的站点,或评分下降 10 点或更多。

审计哪些站点
从托管文章的域名开始。然后对您想要进行基准对比的两个或三个同行站点运行相同的审计。使用 compare 功能。它最多接受 20 个域名,仅需 1 积分,因此同行检查成本几乎为零。
跳过长尾。每个额外的站点都会增加人员需要阅读的日志噪音。对二十个不相关的域名进行基准对比,对您自身的参考价值非常有限。
将密钥保留在日志之外
定时作业每次运行都会读取其密钥,因此无需登录步骤。需要保护的唯一对象是密钥本身。它有三个明显的泄露点:提交、打印的环境变量和代理记录的 URL。关闭每一个泄露点。
使用密钥库,而不是仓库中的文件
将密钥粘贴到 CI 提供商的密钥库中,或仅由作业用户可读的环境文件中。切勿提交它。一个回显其环境的步骤会将其打印出来,因此不要编写这样的步骤。
通过 Header 发送密钥
Bearer Header 可将密钥排除在大多数访问日志之外,因为 URL 会被记录,而 Header 通常不会。查询字符串形式也可以,但会在每个看到请求的代理中留下副本。
限制谁可以读取密钥库
仅授予维护作业的人员读取权限,其他人不得访问。在作业交接时审查该列表。
许多人可读的密钥,终有一天会被粘贴到聊天窗口中。
在记录之前验证回复
收到的回复尚不一定是可用的回复。每次使用相同的顺序。只写入通过验证的内容,并记录其余部分。被拒绝的回复是证据,下次调试作业的人需要看到它。
首先检查状态和 ok 字段
读取 HTTP 状态码,然后读取正文中的 ok 字段。状态码为 200 但 ok 为 false 仍是一次失败的调用,日志应如实记录。
在任何写入之前解析 JSON
在解压、解析或追加任何内容之前,确认正文是有效的 JSON。在运行器不稳定时可能会发生截断下载。写入日志的损坏文件在有人打开之前看起来是正常的。
将空列表视为疑问
对于上月有数据的站点,空结果是一个疑问,而非事实。在任何人收到警报之前,检查域名的拼写,包括前缀 www.。
用于起步的工作流文件
将密钥存储为名为 SBB_KEY 的仓库密钥。cron 表达式在每月 1 日 06:00 UTC 运行。
yaml
name: monthly-link-audit
on:
schedule:
- cron: '0 6 1 * *'
workflow_dispatch: {}
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Overview (free)
run: |
curl -fsS "https://seoblogbot.com/api.php?action=overview&q=example.com" > overview.json
- name: Refdomains (2 credits)
env:
SBB_KEY: ${{ secrets.SBB_KEY }}
run: |
curl -fsS -H "Authorization: Bearer $SBB_KEY" \
"https://seoblogbot.com/api.php?action=refdomains&q=example.com&per=500" > refdomains.json
- name: Log credits
run: jq -r '._credits' refdomains.json >> credits.log
什么会出错以及日志显示什么
| 症状 | 可能原因 | 第一步操作 |
|---|
| HTTP 401 | 密钥缺失或已轮换 | 重新创建密钥,运行 workflow_dispatch |
|---|
| HTTP 402 | 积分耗尽 | 从账户页面充值,重新运行 |
|---|
| 已知站点出现空行 | 索引刷新中或域名拼写错误 | 一天后重试;检查 www. |
|---|
| 评分波动几个点 | 月度刷新 | 无需操作;查看趋势 |
|---|
| 评分下降 10+ 点 | 链接丢失或大规模刷新变更 | 拉取 refdomains 并进行差异比较 |
|---|
普通服务器上的 Cron从 crontab 行运行相同的命令。将密钥保留在仅由作业用户可读的环境文件中,并将日志记录到轮换的文件中。

成本及读取位置
对一个站点进行月度审计,在拉取两个列表时成本为 4 积分,即 $0.0004。概览调用是免费的。因此,没有变化的月份成本为零。
如果您的团队每天在多个站点发布十篇文章,审计仍然是每个站点每月一次作业,而不是每篇文章一次作业。这保持了计数较小且日志可读。
添加第二个站点时,请复制作业而不是扩大它。每个域名一个工作流可保持每个站点的日志,并使故障易于追溯至其所有者。
较大的成本通常是 CI 提供商的分钟数,而不是我们的积分。成本表 将两者并列,以便您决定首先调整哪一项。
让第一次运行打印 _credits。相信回复内容胜过任何表格。预检门控指南 涵盖了在此之前的草稿侧检查。
GitHub 定时任务在 UTC 下运行,因此 06:00 的启动时间对于每个团队来说对应不同的本地小时。将时区写入运行手册,以免人员看到日志时感到惊讶。
关于运行审计的问题
大多数这些问题来自刚刚首次调度作业的团队。
这是 Google 反向链接检查器 API 吗?
这是基于我们自有 API 构建的审计,而非 Google 产品。Google 未发布通用的反向链接 API,因此数据来自我们自己的爬虫和索引。
审计可以在每次构建时运行吗?
可以,但月度 refdomains 拉取无需在每次构建时运行。每次发布时运行免费概览,每月运行一次付费拉取。
如果有门控,我还需要审计吗?
是的,如果您通过插件或 CDN 发布。门控查看您的草稿,而审计查看上线页面。每个都能捕获另一个无法看到的故障。
如果作业中途失败怎么办?
将每个步骤的结果写入其自己的文件,以便失败的拉取保留概览数据。从失败的步骤重新运行,而不是从头开始,以避免为相同的拉取支付两次费用。
我应该为每个站点预算多少积分?
为每个站点每月预算 4 积分用于两次付费拉取,加上门控在草稿上花费的任何积分。免费概览不会增加该数字,日志会显示实际总额。
为什么几天内的两次运行结果不一致?
索引大约每月刷新一次,因此每日变化通常是噪音。在打开事件之前,将本月的快照与上月的快照进行比较。
运行手册签署
- 密钥已存在,且工作流已手动运行过一次。
- 日志文件记录日期、URL、调用次数和
_credits。 - 有人负责警报频道。
- 作业将月度数据视为月度数据。
- 审计本身的故障会触发人员警报。