7.0 KiB
7.0 KiB
热点雷达 (Hotspot Radar)
Sage 框架模块 — 指定来源的热点聚合分析平台,支持动态添加来源。
功能
- 11 个内置平台解析器:微博/知乎/百度/头条/B站/抖音/36氪/GitHub/HackerNews/V2EX/RSSHub
- 4 种可配置提取器:json_path / css(轻量) / regex / rss
- 每条来源自带 parser_config:JSON 格式的提取规则,同类型不同来源可用不同规则
- 五维分析:时效 / 热度 / 内容 / 传播 / 受众,每维度 0-100 分
- 自动状态分类:7 天半衰期指数衰减模型,emerging → rising → hot → cooling → expired
- 抓取日志:每次执行一条审计记录(耗时/成功数/错误/HTTP状态码)
- 预警规则:热度阈值 / 速度阈值 / 情感变化触发
目录结构
hotspot/
├── hotspot/ # Python 包
│ ├── __init__.py # public API: run_fetch, run_analysis, get_stats
│ ├── engine.py # 抓取引擎 — 调度→fetch→extract→save→log
│ ├── analysis.py # 五维分析 + 衰减模型状态分类
│ ├── parsers.py # 11 内置解析器 + 4 通用提取器
│ └── db.py # 数据库操作 (CRUD helpers)
├── json/ # Sage 表定义 (6 张表)
├── wwwroot/hotspot/ # Sage Web 层
│ ├── index.ui # 仪表盘 UI (7 统计卡片 + 6 标签页)
│ ├── fetch_now.dspy # 触发抓取 (薄封装)
│ ├── analyze.dspy # 触发分析 (薄封装)
│ └── stats.dspy # 统计查询 (薄封装)
├── ddl/mysql.sql # 建表 SQL (6 张表 + 索引)
└── install/ # 部署片段
├── load_path_append.txt # 追加到 load_path.py 的路径
└── menu_append.json # 追加到 menu.ui 的菜单项
安装
1. 复制文件到 Sage 部署目录
SAGE_ROOT=/path/to/sage
git clone git@git.opencomputing.cn:yumoqing/hotspot.git /tmp/hotspot
# Python 包
cp -r /tmp/hotspot/hotspot $SAGE_ROOT/
# 表定义
cp /tmp/hotspot/json/hotspot_*.json $SAGE_ROOT/json/
# Web UI + 端点
cp -r /tmp/hotspot/wwwroot/hotspot $SAGE_ROOT/wwwroot/
2. 建表
mysql -u <user> -p sage < /tmp/hotspot/ddl/mysql.sql
3. 注册权限
打开 $SAGE_ROOT/load_path.py,找到末尾的 """ 结束符,在它前面插入 install/load_path_append.txt 的内容。
cd /tmp/hotspot
# 找到 SAGE_ROOT/load_path.py 中最后一个 """ 的前一行
# 把 install/load_path_append.txt 的内容粘贴进去
# 然后:
cd $SAGE_ROOT && python load_path.py
4. 添加菜单
打开 $SAGE_ROOT/wwwroot/menu.ui,在 items 数组末尾追加 install/menu_append.json 的内容(注意前面加逗号)。
5. 重启 Sage
访问 /hotspot。
使用流程
- 添加来源 → 进入「来源管理」标签页,点击新增
- 类型选
api配合parser=builtin使用内置解析器 - 或选
rss/api配合parser=json_path自定义提取规则
- 类型选
- 配置提取规则 → 在
parser_config字段填入 JSON:
或自定义:{"parser": "builtin", "builtin_name": "weibo_hot"}{ "parser": "json_path", "item_path": "$.data.list[*]", "field_map": { "title": "word", "url": "link", "heat_score": "hotValue" } } - 配置调度 → 在「调度配置」标签页添加 cron 或间隔
- 执行抓取 → 仪表盘点击「立即抓取全部来源」
- 查看日志 → 「抓取日志」标签页检查成功率/错误详情
- 执行分析 → 点击「执行分析」计算五维评分和状态
- 浏览热点 → 「热点条目」标签页按状态筛选
- 设置预警 → 「预警规则」标签页配置自动通知
内置解析器
零配置即用(9个)
| 解析器名 | 平台 | 实时热度 | 需要认证 |
|---|---|---|---|
weibo_hot |
微博热搜 | ✅ | 无 — 公开接口 |
zhihu_hot |
知乎热榜 | ✅ | 无 |
baidu_hot |
百度热搜 | ✅ | 无 |
toutiao_hot |
头条热榜 | ✅ | 无(需 Referer 头) |
bilibili_hot |
B站热门 | ✅ | 无 |
36kr_hot |
36氪热榜 | ✅ | 无 |
github_trending |
GitHub Trending | ✅ | 无 — 匿名 60次/h,Token 5000次/h |
hackernews |
HackerNews | ✅ | 无 |
v2ex_hot |
V2EX 热帖 | ✅ | 无 |
需要配置(2个)
| 解析器名 | 平台 | 需要什么 | 怎么获取 |
|---|---|---|---|
rsshub |
RSSHub | RSSHub 实例地址 | 自建 docker run rsshub/rsshub 或用公共服务 |
douyin_hot |
抖音热点 | ⚠️ 无官方 API | 第三方接口不稳定,建议用浏览器抓取 |
添加来源时只需选
parser=builtin+builtin_name=weibo_hot即可,无需申请任何 Key。
提取器类型
| parser 值 | 适用场景 | 配置要点 |
|---|---|---|
builtin |
使用内置解析器 | 设置 builtin_name |
json_path |
REST API 返回 JSON | item_path + field_map |
css |
HTML 页面 (轻量) | item_selector + field_map — 仅支持 <a> 标签提取,完整 CSS 需引入 BeautifulSoup |
regex |
非结构化文本 | item_regex (命名捕获组) + field_map |
rss |
RSS/Atom feed | 自动解析,无需额外配置 |
抓取频率建议
| 解析器 | 推荐间隔 | 原因 |
|---|---|---|
weibo_hot |
5-10 分钟 | 热搜榜实时变动 |
zhihu_hot |
10-15 分钟 | 热榜更新较快 |
baidu_hot |
10-15 分钟 | 同知乎 |
toutiao_hot |
15-20 分钟 | 新闻类更新稍慢 |
bilibili_hot |
30 分钟 | 视频热度积累需时间 |
36kr_hot |
30-60 分钟 | 一天几十条 |
github_trending |
2-4 小时 | 限速 60次/h |
hackernews |
15-30 分钟 | 首页排序变化频繁 |
v2ex_hot |
15-30 分钟 | 社区帖子更新快 |
rsshub |
取决于源 | RSS 源自身有间隔 |
默认 30 分钟是安全的——7 天半衰期模型下远远小于衰减窗口。
状态分类逻辑
热度衰减: adjusted_heat = raw_heat × e^(-hours_alive / 168)
状态判定:
hours_alive > 336 (14天) → expired
336 > hours_alive > 168 → cooling
adjusted_heat > 5000 → hot
adjusted_heat > 500 → rising (velocity > 50) / emerging
adjusted_heat > 100 → rising (velocity > 100) / emerging
其他 → emerging
依赖
- Sage >= 0.0.1
- aiohttp (Python, 用于异步 HTTP 请求)
- MySQL / MariaDB
已知限制
- CSS 提取器为轻量正则实现,复杂页面结构建议使用
json_path或builtin - 抖音(
douyin_hot)使用第三方聚合接口dy.feigua.cn,非官方数据源,builtin_name=douyin_hot仅作为参考 - 无 Headless Browser 集成(需单独部署 Playwright/Selenium)
- GitHub 匿名访问限速 60次/小时,高频使用建议配 Personal Access Token 到 headers