跳到正文
阿里雲開發者社區 AI·· 2 小時前AI 評分55

TrendRadar 部署實錄:以零成本每小時聚合全網熱榜

保持AI时代的竞争力!我用0成本每小时获取最新热榜——TrendRadar 部署实录

AI 導讀

作者記錄了 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

1000007914.png

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 一张图说明

TrendRadar热点聚合全景海报.png

🛠️ 三、部署过程(完整可复现)

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 仓库设置

  1. 两个选择
    1. 直接fork源仓库https://github.com/sansan0/TrendRadar,可能出现无workflow的问题按readme文档解决或者参考这篇文章中下面的“第六章常见问题速查表”(推荐)
    2. fork我的仓库https://github.com/10021725/TrendRadar.git
  2. Settings → Pages → Source:本次初始为 GitHub Actions(这一步直接决定了后面的 404,见 §4.5)。
  3. Settings → Actions → General:
    • Actions permissions → Allow all actions and reusable workflows ✅(实测已是此值)
    • Workflow permissions → 实测为 Read repository contents and packages permissions
  4. Secrets:为你期望推送平台的webhook url或机器人,以企微为例

image\_120.png

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

image\_121.png

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 api PUT 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+ 安全策略变更,默认档案(真实用户数据目录)禁止远程调试。
  • 解法与二次踩坑:
    1. 改用 --user-data-dir=<专用目录> 启动 → 端口可用;
    2. 试图从真实档案复制 Local State + Default/Network/Cookies 以复用 GitHub 登录态 → 失败:受控窗口仍显示 Sign in / Sign up;
    3. 根因:Chrome 采用 app-bound encryption(App-Bound Encryption),Cookie 密文绑定到原始档案/进程,跨目录复制后无法解密;
    4. 最终解法:在受控窗口里手动登录一次,登录态持久保存在专用档案,后续复用不再需要密码。
  • 工具: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 实体(&#x1F4D8;),文件保持纯 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 排查网络/平台限流,勿盲目加时

📎 七、附:本次产生的文件与链接

类型 路径 / 地址
上游仓库 https://github.com/sansan0/TrendRadar
部署仓库 https://github.com/10021725/TrendRadar
线上站点 https://10021725.github.io/TrendRadar/
运行记录 https://github.com/10021725/TrendRadar/actions
官方演示站 https://sansan0.github.io/TrendRadar/

本文档基于 2026-10-23 ~ 10-24 的真实部署过程整理。 所有命令输出、报错原文、耗时与体积数据均可复现核验;标注「估算」的部分为人工口径推算,不作为实测结论。

來源:阿里雲開發者社區 AI · developer.aliyun.com