169 lines
6.3 KiB
Markdown
169 lines
6.3 KiB
Markdown
# 热点雷达 (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 部署目录
|
||
|
||
```bash
|
||
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. 建表
|
||
|
||
```bash
|
||
mysql -u <user> -p sage < /tmp/hotspot/ddl/mysql.sql
|
||
```
|
||
|
||
### 3. 注册权限
|
||
|
||
打开 `$SAGE_ROOT/load_path.py`,找到末尾的 `"""` 结束符,在它**前面**插入 `install/load_path_append.txt` 的内容。
|
||
|
||
```bash
|
||
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`。
|
||
|
||
## 使用流程
|
||
|
||
1. **添加来源** → 进入「来源管理」标签页,点击新增
|
||
- 类型选 `api` 配合 `parser=builtin` 使用内置解析器
|
||
- 或选 `rss`/`api` 配合 `parser=json_path` 自定义提取规则
|
||
2. **配置提取规则** → 在 `parser_config` 字段填入 JSON:
|
||
```json
|
||
{"parser": "builtin", "builtin_name": "weibo_hot"}
|
||
```
|
||
或自定义:
|
||
```json
|
||
{
|
||
"parser": "json_path",
|
||
"item_path": "$.data.list[*]",
|
||
"field_map": {
|
||
"title": "word",
|
||
"url": "link",
|
||
"heat_score": "hotValue"
|
||
}
|
||
}
|
||
```
|
||
3. **配置调度** → 在「调度配置」标签页添加 cron 或间隔
|
||
4. **执行抓取** → 仪表盘点击「立即抓取全部来源」
|
||
5. **查看日志** → 「抓取日志」标签页检查成功率/错误详情
|
||
6. **执行分析** → 点击「执行分析」计算五维评分和状态
|
||
7. **浏览热点** → 「热点条目」标签页按状态筛选
|
||
8. **设置预警** → 「预警规则」标签页配置自动通知
|
||
|
||
## 内置解析器
|
||
|
||
### 零配置即用(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 | 自动解析,无需额外配置 |
|
||
|
||
## 状态分类逻辑
|
||
|
||
```
|
||
热度衰减: 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
|