TrendRadar 部署實錄:以零成本每小時聚合全網熱榜
保持AI时代的竞争力!我用0成本每小时获取最新热榜——TrendRadar 部署实录
作者記錄了 TrendRadar 的實際部署:GitHub Actions 每小時第 33 分聚合熱榜,並由 GitHub Pages 發佈報告,示例站點為 https://10021725.github.io/TrendRadar/#all。文章提供可復現設定及 12 類踩坑排查;本次部署採用零成本基礎同步,沒有啟用可選 AI 分析。
2026-10-24 4
版权
版权声明:
本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议》和 《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
简介: TrendRadar 是一款零成本、每小时自动聚合全网热榜(微博/知乎/抖音等)的开源工具。本文为真实部署实录,含完整可复现步骤、GitHub Actions+Pages 自动化配置及12类踩坑详解,助你快速搭建个人热点雷达站,日省7–13小时,专注选题而非刷榜。(239字)
一份基于真实操作过程整理的部署复现文档。所有数据(Star 数、运行记录、耗时、站点体积、报错原文)均来自实际部署时的命令输出与页面抓取,你可以直接把这篇文章丢给AI让它帮你部署可以节约大量时间。
🎯 一、成果与价值
1.1 实际跑通的效果(企业微信推送截图),站点示例:https://10021725.github.io/TrendRadar/#all

1.2 省下来的时间(估算,标注清楚)
⚠️ 以下为估算值,非实测统计。计算依据:手动刷 5–8 个平台热榜,按每个平台 2–3 分钟浏览 + 记录计,约 15–30 分钟/天;自动化后每日只需打开 1 次报告页面,约 2–3 分钟/天。单月可节省约 7–13 小时(按 30 天计)。此为个人体验口径,不同创作者差异较大。
1.3 在 AI 时代,它解决的到底是什么
- 信息过载从「你刷不完」变成「机器替你刷完」:热榜每小时自动聚合成一页,你打开即得全景,不再需要 8 个 App 轮流点。
- 从「信息」到「选题」的断层被接上:热榜不是终点。雷达页 → 选题池 → 多平台同步发布,这条链路在本项目的「笔记发布工作台」里已经串起来,热榜是这条流水线的上游水源。
- 对个人创作者:等于多了一个 24 小时不休息的选题助理;对小团队,等于一份统一口径的热点简报,不再靠群里人工转述。
- AI 的位置是「增稠」而非「代替」:TrendRadar 负责高频、无判断力的聚合;AI 分析(可选
AI_ANALYSIS_ENABLED/AI_API_KEY)负责在聚合之上做解读。判断权仍在人手里。
📦 二、项目介绍
2.1 一张图说明

🛠️ 三、部署过程(完整可复现)
3.1 架构总览
flowchart LR
subgraph TRIG["触发:GitHub Actions(每小时第 33 分)"]
A["GitHub Actions<br/>ubuntu-latest<br/>cron 33 * * * *"] --> B["actions/checkout@v6"]
B --> C["actions/setup-python@v6<br/>Python 3.12"]
C --> D["astral-sh/setup-uv@v7"]
D --> E["uv sync --frozen --no-dev"]
E --> F["uv run python -m trendradar"]
F --> G["生成 index.html"]
end
subgraph PUB["发布:GitHub Pages(本次新增)"]
H["Prepare Pages artifact<br/>gh_pages/index.html"]
I["actions/configure-pages@v5"]
J["actions/upload-pages-artifact@v3"]
K["actions/deploy-pages@v4"]
L[("GitHub Pages")]
H --> I --> J --> K --> L
end
subgraph OPT["可选分支(本次未启用)"]
M["Cloudflare Pages<br/>cloudflare/wrangler-action@v3"]
N["推送渠道<br/>飞书 / 钉钉 / 邮件 / ntfy / Telegram"]
end
G --> H
F --> M
F --> N
L --> O["浏览器访问<br/>10021725.github.io/TrendRadar/"]
本次走的是左半边(Actions + GitHub Pages);右上 Cloudflare Pages 为上游内置的可选分支,需要额外三个 Secret(见 5.3)。
3.2 环境准备
| 项 | 本次实测版本 / 状态 |
|---|---|
| 操作系统 | Windows 11(win32) |
| Git | 2.55.0.windows.3 |
GitHub CLI gh |
已认证 |
| Python | 由 actions/setup-python@v6 装 3.12(无需本地装) |
| uv | 由 astral-sh/setup-uv@v7 装(无需本地装) |
| Node(本机辅助) | 22.22.2(托管版),用于自动化脚本 |
| 浏览器 | Chrome 155.0.8059.80 |
建仓方式:按 README 推荐使用 Use this template 创建仓库(不要用github的fork方式)。这一步正是后面「No workflows found」的直接诱因。
小白的话可以直接上:电脑+workbuddy(dsh等)+github skill
3.3 仓库设置
- 两个选择
- 直接fork源仓库https://github.com/sansan0/TrendRadar,可能出现无workflow的问题按readme文档解决或者参考这篇文章中下面的“第六章常见问题速查表”(推荐)
- fork我的仓库https://github.com/10021725/TrendRadar.git
- Settings → Pages → Source:本次初始为
GitHub Actions(这一步直接决定了后面的 404,见 §4.5)。 - Settings → Actions → General:
- Actions permissions →
Allow all actions and reusable workflows✅(实测已是此值) - Workflow permissions → 实测为
Read repository contents and packages permissions
- Actions permissions →
- Secrets:为你期望推送平台的webhook url或机器人,以企微为例

- 回到Actions 找到“Get Hot News” 点击 run
- TrendRadar 有 7 天活跃机制——距首次运行超 7 天会自动停用 workflow。可以让workbuddy给你创建一个定时任务-- 每 6 天自动「签到」

3.4 关键配置文件(以下3.4-3.6没有特殊自定义需求可以不看)
① .github/workflows/crawler.yml(上游原版要点)
name: Get Hot News
on:
schedule:
- cron: "33 * * * *" # 每小时第 33 分
workflow_dispatch: # 支持手动触发
permissions:
contents: read
actions: write
jobs:
crawl:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v6
with: {
fetch-depth: 1, clean: true }
- name: Check Expiration # 试用版 7 天校验(见 §4.6)
run: |
gh api "repos/${
{ github.repository }}/actions/workflows/$WORKFLOW_FILE/runs" --jq '.total_count'
- uses: actions/setup-python@v6
with: {
python-version: "3.12" }
- uses: astral-sh/setup-uv@v7
- run: uv sync --frozen --no-dev
- run: uv run python -m trendradar
# 可选:Cloudflare Pages 部署(需 3 个 Secret)
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${
{
secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${
{
secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy cloudflare_dist --project-name=${
{
secrets.CLOUDFLARE_PROJECT_NAME }}
② 本次新增的 GitHub Pages 部署段(实测可用)
permissions:
contents: read
actions: write
pages: write # 新增
id-token: write # 新增
- name: Prepare GitHub Pages artifact
if: success()
run: |
if [ ! -f index.html ]; then echo "index.html not found"; exit 1; fi
rm -rf gh_pages && mkdir -p gh_pages && cp index.html gh_pages/index.html
- name: Setup Pages
if: success()
uses: actions/configure-pages@v5
- name: Upload Pages artifact
if: success()
uses: actions/upload-pages-artifact@v3
with:
path: gh_pages
- name: Deploy to GitHub Pages
if: success()
uses: actions/deploy-pages@v4
③ config/config.yaml:本次未修改,沿用模板默认配置(关键词、显示模式、调度等)。
3.5 提交修改(推荐用 gh API,避免网页编辑器踩坑)
# 1) 取当前文件 sha
sha=$(gh api repos/10021725/TrendRadar/contents/.github/workflows/crawler.yml?ref=master --jq '.sha')
# 2) 构造补丁后的文件内容并提交
python - <<'PY'
import base64, json, subprocess
content = open('crawler_patched.yml', encoding='utf-8').read()
sha = subprocess.run(['gh','api','repos/10021725/TrendRadar/contents/.github/workflows/crawler.yml?ref=master','--jq','.sha'],
capture_output=True, text=True).stdout.strip()
body = json.dumps({'message':'ci: add GitHub Pages deploy steps',
'content':base64.b64encode(content.encode()).decode(),
'sha':sha,'branch':'master'})
subprocess.run(['gh','api','-X','PUT',
'repos/10021725/TrendRadar/contents/.github/workflows/crawler.yml','--input','-'],
input=body, text=True, encoding='utf-8')
PY
3.6 启动与验证
# 手动触发(cron 也会每小时自动触发)
gh workflow run crawler.yml --repo 10021725/TrendRadar --ref master
# 查看运行记录
gh run list --repo 10021725/TrendRadar --workflow crawler.yml --limit 3
# 实际输出:
# in_progress Get Hot News master workflow_dispatch 39970317170 19s
# completed success Get Hot News master workflow_dispatch 39969545175 54s
# 查看结论与步骤
gh run view <run-id> --repo 10021725/TrendRadar --json status,conclusion,jobs
# 实际输出:{"conclusion":"success","jobs":[{"conclusion":"success","name":"crawl"}]}
# 验证站点
curl -s -o /dev/null -w "%{http_code}" -L https://10021725.github.io/TrendRadar/ # → 200
curl -s -L https://10021725.github.io/TrendRadar/ | grep -o "<title>[^<]*</title>" # → <title>热点新闻分析</title>
验证结果留档:
{"conclusion":"success","jobs":[{"conclusion":"success","name":"crawl"}]}
pages:200
<title>热点新闻分析</title>
136806 # 报告字节数
🧨 四、踩坑与解决(全部为真实遇到的问题)
4.1 Actions 页显示「No workflows found」,但仓库里明明有文件
- 现象:
/actions左侧 Workflows 列表为空,页面提示No workflows found;仓库.github/workflows/下实际存在crawler.yml/clean-crawler.yml/docker.yml/issue-guard.yml。 - 根因:仓库是 Use this template / 上传建仓(初始仅 1 个
Initial commit),GitHub 未对初始导入的 workflow 文件建立索引。直接访问actions/workflows/crawler.yml返回This workflow does not exist.,但raw.githubusercontent.com能正常读到文件内容 —— 这就是「文件在、workflow 不在」的决定性证据。 - 解法:对 workflow 文件做一次任意提交,触发 GitHub 重新索引。实测先新建
reindex.yml(此时列表出现Reindex但仍无Get Hot News),再对crawler.yml追加一行注释并提交,列表随即出现Get Hot News。 - 工具:GitHub 网页编辑器 /
gh api。 - 验证:修复后
Workflows列表显示Get Hot News;运行页可见workflow_dispatch入口。
📌 规律:上传/模板建仓的 workflow 需逐个文件触碰才会被索引,只碰一个文件不会带动其他文件。
4.2 workflow 跑成功,站点却 404
- 现象:Run #1
success(54 秒),但https://10021725.github.io/TrendRadar/返回404 Site not found。 - 根因:Pages 的 Source 是
GitHub Actions,而上游crawler.yml里没有deploy-pages步骤——它只内置了 Cloudflare Pages 部署分支(cloudflare/wrangler-action@v3)。GitHub Actions模式要求 workflow 自行调用actions/deploy-pages,产物不会自动发布。产物只存在于 runner 的工作区,runner 一销毁就没了。 - 解法:按 §3.4② 补上 4 个步骤与 2 项权限,用
gh api提交。 - 工具:
gh api repos/.../contents/...(PUT)。 - 验证:Run #2
success;curl站点返回200,标题热点新闻分析,体积 136,806 字节,内容含真实榜单条目。
📌 顺带澄清一个易混点:仓库根目录确实存在
index.html(26,844 字节,Initial commit自带),但它不是本次跑出来的报告,也不会被 workflow 自动回写——trendradar/__main__.py里没有任何git push逻辑,且上游 workflow 权限为contents: read。本次之所以能拿到 136,806 字节的实时报告,靠的正是新增的 artifact 发布链路。
4.3 网页编辑器改 workflow,改了等于没改
- 现象:在 GitHub 网页编辑器里
Ctrl+A+ 整段替换后提交,commit 成功、跳转 blob 页面,但raw拉下来的文件与改前逐字节相同(新增内容全部丢失)。 - 根因:GitHub 用的是 CodeMirror 6,虚拟滚动只渲染可视行,
Ctrl+A只选中了已渲染的那部分;再insertText写入,编辑器内容与提交内容不一致,导致改动被丢弃(提交时校验通过的是旧内容)。 - 解法:放弃网页编辑器,改用
gh apiPUT contents 接口提交完整文件内容(§3.5)。 - 工具:
gh api。 - 验证:提交后
raw文件体积 9,819 → 10,643 字节,且新增段落deploy-pages@v4可被 grep 到。
4.4 Chrome 155 不允许在默认档案上开调试端口
- 现象:
chrome.exe --remote-debugging-port=9226启动后报DevTools remote debugging requires a non-default data directory,9226 端口随即失联。 - 根因:Chrome 136+ 安全策略变更,默认档案(真实用户数据目录)禁止远程调试。
- 解法与二次踩坑:
- 改用
--user-data-dir=<专用目录>启动 → 端口可用; - 试图从真实档案复制
Local State+Default/Network/Cookies以复用 GitHub 登录态 → 失败:受控窗口仍显示Sign in / Sign up; - 根因:Chrome 采用 app-bound encryption(App-Bound Encryption),Cookie 密文绑定到原始档案/进程,跨目录复制后无法解密;
- 最终解法:在受控窗口里手动登录一次,登录态持久保存在专用档案,后续复用不再需要密码。
- 改用
- 工具:chrome-cdp-takeover 技能 + playwright-core
connectOverCDP(navigator.webdriver保持false)。 - 验证:页面
meta[name=user-login]返回10021725,loggedIn: true。
4.5 本机代理劫持了 localhost,全局失联
- 现象:CDP 明明在监听,
curl http://127.0.0.1:9226/json/version返回502 upstream connect failed;gh报unexpected EOF/TLS handshake timeout。 - 根因:环境变量
HTTP_PROXY/HTTPS_PROXY=http://127.0.0.1:10209把127.0.0.1也送进了代理。 - 解法:本地回环请求一律绕过代理 ——
curl --noproxy '*'、NO_PROXY="*" no_proxy="*";gh调用清空HTTP_PROXY="" HTTPS_PROXY=""。 - 工具:curl / 终端环境变量。
- 验证:
/json/version正常返回Browser: Chrome/155.0.8059.80。
4.6 全网断连约 2 分钟(连百度都不通)
- 现象:
api.github.com、baidu.com全部000;浏览器ERR_CONNECTION_CLOSED。 - 根因:本机代理进程(
127.0.0.1:10209)瞬时不可用,非 GitHub 侧故障。 - 解法:不盲目重试风暴,采用轮询等待:每 25 秒探测一次,第 5 次(≈2 分钟后)恢复
200。 - 教训:网络类报错先分清「对端故障」与「本地链路故障」,前者等,后者换通道。
- 验证:恢复后
gh run view与curl均正常。
4.7 上游的「试用版 7 天」会自动停用 workflow
- 现象:翻
crawler.yml时发现Check Expiration步骤会以首次运行时间为基准,超过 604800 秒(7 天)就gh workflow disable并退出。 - 根因:上游为控制公共算力设置的活跃度门槛(README 原文:GitHub Actions 是共享公共资源)。
- 解法:
Check In的实质是清空旧的运行记录,从而重置「首次运行时间」基准。已落地为定时任务「TrendRadar 签到续期」:每 6 天 10:00 删除旧运行记录 → 检查gh workflow list若被禁用则gh workflow enable→curl探活站点 → ntfy 推送到手机。 - 验证:定时任务已创建(id
c6818469-a2fb-4471-91fc-316194d7fb76),下次触发 2026-10-29 10:00。
4.8 静态页发布管线会吃掉 4 字节 UTF-8 字符
- 现象:工作台发布上线后,7 个平台图标里 📘 🔵 💬 🐻 🌩️ 全部变成
�,而 ⛏️ ☁️ 正常;卡片标题的 🚀📡🖼️🔐 同样损坏。 - 根因:发布环节按字节处理文件,代理对型字符(U+1F300+,4 字节 UTF-8)被丢弃;BMP 字符(U+26CF、U+2601)与中文(3 字节)不受影响。规律可验证:损坏的全是星形平面字符。
- 解法:源码中把这类字符写成 HTML 实体(
📘),文件保持纯 ASCII 过管线,浏览器照常渲染 emoji。 - 工具:Python 脚本批量替换。
- 验证:线上版替换符计数
0;实抓 DOM 得 7 个平台图标文本全部正确、尺寸均为 27×27,卡片标题 emoji 全部正常。
4.9 附:本文档标题里的「AI」从哪来
- 说明:TrendRadar 本身是确定性聚合工具,核心是抓取 + 去重 + 排序;它的「AI」体现在可选的 AI 热点解读(
AI_ANALYSIS_ENABLED、AI_API_KEY、AI_MODEL,任意 Anthropic 协议兼容端点)与 MCP 对话分析服务wantcat/trendradar-mcp。本次部署未启用 AI 分析(未配置 Secret),走的是零成本基础同步路径 —— 此处如实标注,避免读者误以为默认就有 AI 解读。
✅ 五、部署检查清单
| # | 检查项 | 判定标准 | 本次结果 |
|---|---|---|---|
| 1 | 仓库已创建 | .github/workflows/ 下有 crawler.yml |
✅ |
| 2 | workflow 已被 GitHub 索引 | Actions 页 Workflows 列表非空 | ✅(修复后) |
| 3 | Actions 权限允许 | Allow all actions and reusable workflows |
✅ |
| 4 | workflow 权限含 pages 写 | pages: write + id-token: write |
✅(本次补加) |
| 5 | workflow 含部署步骤 | configure-pages / upload-pages-artifact / deploy-pages |
✅(本次补加) |
| 6 | Pages Source 正确 | 与部署方式匹配(Actions 模式须配 deploy-pages) | ✅ |
| 7 | 手动触发成功 | gh workflow run 后 run 状态 success |
✅ 54s |
| 8 | 站点返回 200 | curl -o /dev/null -w "%{http_code}" |
✅ 200 |
| 9 | 报告内容真实 | 标题 + 榜单条目抽样 | ✅ 知乎/百度热搜/微博/今日头条/抖音 |
| 10 | 定时任务已启用 | 每小时 :33 自动运行 | ✅ |
| 11 | 签到保活已配置 | ≤6 天一次重置 7 天计时 | ✅ 定时任务 |
| 12 | 推送渠道(如需) | Secret 已填且测试通过 | ✅ 企微 |
🧰 六、常见问题速查表
| 症状 | 最可能原因 | 一句话解决 |
|---|---|---|
Actions 页 No workflows found |
模板/上传建仓,workflow 未索引 | 对每个 workflow 文件做一次任意提交 |
直连 actions/workflows/crawler.yml 报不存在,但 raw 能读 |
同上 | 同上 |
| 运行 success 但站点 404 | Pages Source=GitHub Actions 而 workflow 无 deploy-pages | 补 deploy-pages 段 + pages: write |
| 站点 404 且 Pages Source=Deploy from a branch | 产物未回写仓库根目录 | 用 artifact 方式发布,或确认产物已 commit |
| 网页编辑器改文件没生效 | CodeMirror 虚拟滚动,Ctrl+A 选不全 |
改用 gh api PUT contents |
curl 127.0.0.1 502 / gh EOF |
代理劫持回环地址 | --noproxy '*' / 清空 HTTP_PROXY |
| 全部网站 000 | 本地代理进程挂了 | 等 2 分钟轮询恢复 |
| Chrome 拒绝调试端口 | Chrome 136+ 禁止默认档案远程调试 | 加 --user-data-dir 换专用档案 |
| 复制 Cookie 到新档案后仍未登录 | App-Bound Encryption 绑定原档案 | 在专用窗口手动登录一次 |
线上 emoji 变 � |
发布管线丢 4 字节 UTF-8 | 星形平面字符改写成 HTML 实体 |
| 7 天后 workflow 变 disabled | 上游试用版活跃度机制 | 删除旧运行记录重置计时(已自动化) |
| 单次运行超过 15 分钟被取消 | workflow timeout-minutes: 15 |
排查网络/平台限流,勿盲目加时 |
📎 七、附:本次产生的文件与链接
本文档基于 2026-10-23 ~ 10-24 的真实部署过程整理。 所有命令输出、报错原文、耗时与体积数据均可复现核验;标注「估算」的部分为人工口径推算,不作为实测结论。
來源:阿里雲開發者社區 AI · developer.aliyun.com