docs: document duration efficiency, up follower snapshot and nav split
This commit is contained in:
1 parent
c0b0286395
commit
cb9e8e031b
2 files changed
+101
-22
No files matched your search
+50
-10
@@ -100,6 +100,10 @@ uv run python app.py run --once
|
||||
uv run python app.py snapshot
|
||||
uv run python app.py snapshot --force
|
||||
|
||||
# 回填历史视频的 UP 粉丝数快照(第 9 轮;只补空值)
|
||||
uv run python app.py backfill-followers
|
||||
uv run python app.py backfill-followers --dry-run
|
||||
|
||||
# 检查 Cookie 登录态(P1)
|
||||
uv run python app.py auth-check
|
||||
|
||||
@@ -206,7 +210,7 @@ PRAGMA synchronous = NORMAL;
|
||||
│
|
||||
├── reaction_board/
|
||||
│ ├── config.py # 配置、ENV 覆盖、mtime 热加载
|
||||
│ ├── analytics.py # 热度、增长、互动率与封面工具
|
||||
│ ├── analytics.py # 热度、增长、互动率、时长效率、EB 收缩与封面工具
|
||||
│ ├── database.py # SQLite 连接、迁移、单写队列
|
||||
│ ├── migrations.py # schema_version 与迁移
|
||||
│ ├── scheduler.py # 内置任务调度
|
||||
@@ -228,6 +232,7 @@ PRAGMA synchronous = NORMAL;
|
||||
│ │ ├── telegram_poller.py # getUpdates 与回调分发
|
||||
│ │ ├── folder_sync.py
|
||||
│ │ ├── snapshot.py
|
||||
│ │ ├── up_profile.py # UP 粉丝快照采集与历史回填
|
||||
│ │ └── maintenance.py
|
||||
│ ├── notify/telegram.py # Telegram 消息与按钮
|
||||
│ └── web/ # P2 只读看板
|
||||
@@ -521,24 +526,27 @@ P3 实现说明:
|
||||
| 方法 | 路径 | 用途 |
|
||||
|---|---|---|
|
||||
| `GET` | `/api/overview` | 首页动态、总览指标、容量、采集状态 |
|
||||
| `GET` | `/api/videos` | 视频分页、筛选和排序(支持 added/published/heat/七项/互动/增长) |
|
||||
| `GET` | `/api/videos/{aid}` | 视频详情 |
|
||||
| `GET` | `/api/videos` | 视频分页、筛选和排序(支持 added/published/heat/七项/互动/增长/内容效率) |
|
||||
| `GET` | `/api/videos/{aid}` | 视频详情(含分 P 数、入库时粉丝数、内容/互动效率) |
|
||||
| `GET` | `/api/videos/{aid}/trend` | 七项趋势数据 |
|
||||
| `GET` | `/api/rankings` | 视频榜或 `scope=up` 的 UP 聚合榜 |
|
||||
| `GET` | `/api/ups` | UP 聚合榜单 |
|
||||
| `GET` | `/api/rankings` | 兼容旧链接;`scope=up` 时为 UP 聚合榜 |
|
||||
| `GET` | `/api/ups` | UP 聚合榜单(含总时长、播放·小时、内容效率) |
|
||||
| `GET` | `/api/ups/{mid}` | UP 详情、聚合趋势和视频列表 |
|
||||
| `GET` | `/api/fans` | 粉丝曲线与增量 |
|
||||
| `GET` | `/api/candidates` | 候选池(只读) |
|
||||
| `GET` | `/api/system` | 最近任务、下次任务、备份、黑名单 |
|
||||
| `GET` | `/api/about` | 数据说明页当前口径(配置阈值、权重、覆盖度;无凭据) |
|
||||
|
||||
### 9.2 页面
|
||||
|
||||
| 页面 | 内容 |
|
||||
|---|---|
|
||||
| 首页 | 最新动态优先:今日增量、最新入库、最近发布、增长动态、热度速览、容量与采集状态。 |
|
||||
| 榜单 | 综合热度、七项单项、播放增量、播放增速、互动率、UP 聚合和筛选。 |
|
||||
| 视频详情 | 元数据、七项指标、单指标趋势、快照表、失败标记、同 UP 对比。 |
|
||||
| UP 页 | UP 的全部视频、聚合趋势、单视频对比和平均互动率。 |
|
||||
| 视频(`/videos`) | 内容效率(默认)、综合热度、播放/投币/收藏/评论、互动率、播放增量、播放增速;筛选与搜索。 |
|
||||
| UP主(`/ups`) | 独立入口,不再与视频混排;视频数、总时长、播放·小时、互动·小时等可分别排序。 |
|
||||
| 数据说明(`/about`) | 数据来源与更新、发布时间/入库时间/快照日期、指标公式、时长与成熟窗口筛选、粉丝快照覆盖与已知局限;数值由 `/api/about` 动态读取。 |
|
||||
| 视频详情 | 元数据、分 P 数、七项指标、内容/互动效率、入库时粉丝数、单指标趋势、快照表、同 UP 对比。 |
|
||||
| UP 页 | 该 UP 的全部视频、聚合趋势、单视频对比、总时长与播放·小时、入库时与当前粉丝数。 |
|
||||
| 粉丝页 | 粉丝总数、日增、7 日净增、累计增长(标注起始日期);支持预设和自选日期,范围超过一年时按每月峰值日期聚合;最近记录默认 14 天并显示“较上一成功日”增量;不叠加视频数据。 |
|
||||
| 候选池 | 待确认候选、规则命中、剩余保留时间;操作指向 Telegram/CLI。 |
|
||||
| 系统状态 | 最近扫描、同步、快照、下次运行、备份、鉴权和黑名单。 |
|
||||
@@ -550,7 +558,8 @@ P3 实现说明:
|
||||
- `python app.py serve --preview` 校验标记,缺失时拒绝启动;
|
||||
- 预览配置不包含真实凭据,默认端口 8081,Telegram 关闭;
|
||||
- 预览页面显示固定“预览数据 · 不影响真实数据库”横幅,右上角入口显示“预览”;
|
||||
- 重新生成预览库前必须停止预览服务,避免 Windows 文件占用。
|
||||
- 重新生成预览库前必须停止预览服务,避免 Windows 文件占用;
|
||||
- 第 9 轮起本地不再保留 `data/app.db` 真实副本;重新生成预览时用 `--source` 指向 `data/backup/` 中的真实库备份(如 `app-local-before-reseed-20261101.db`)。
|
||||
|
||||
---
|
||||
|
||||
@@ -589,6 +598,22 @@ interaction_rate = (like + coin + favorite) / max(view, 1)
|
||||
- 互动率榜要求播放至少 100;
|
||||
- 样本不足两天的视频明确标注,不伪造增长数据。
|
||||
|
||||
### 10.3 时长效率与 UP 内容效率(第 9 轮)
|
||||
|
||||
```text
|
||||
内容小时 = duration / 3600
|
||||
内容效率 = view / 内容小时
|
||||
互动效率 = (like + coin + favorite) / 内容小时
|
||||
UP 内容效率 = (Σview + κ·μ₀) / (Σ内容分钟 + κ) * 60
|
||||
```
|
||||
|
||||
- 分母只用总时长,不用分 P 数(B 站播放记在 bvid 上,`view/pages` 无统计含义);
|
||||
- 效率榜要求 `duration >= analytics.min_duration_seconds`(默认 600 秒)且发布满 `analytics.maturity_days`(默认 14 天);
|
||||
- 不引入 `log(age)` 等无界年龄项,避免系统性惩罚老视频;
|
||||
- `duration` 缺失或非正数不参与效率排序;
|
||||
- UP 收缩强度 `κ` 取全库 UP 总内容分钟中位数,`analytics.shrink_minutes` 可覆盖;
|
||||
- 视频数与总时长并列展示、分别排序,不合成单一产出分。
|
||||
|
||||
---
|
||||
|
||||
## 11. 测试与质量要求
|
||||
@@ -615,7 +640,9 @@ uv run python tests/test_moves.py
|
||||
- 看板查询的筛选、分页、增长冷启动与状态过滤;
|
||||
- 只读路由、鉴权、静态资源路径穿越和预览标记校验;
|
||||
- 预览库生成的确定性、单调性、异常样本与真实库隔离;
|
||||
- 粉丝历史 CSV 解析、同日去重、缺口计数与幂等/替换回填。
|
||||
- 粉丝历史 CSV 解析、同日去重、缺口计数与幂等/替换回填;
|
||||
- UP 粉丝快照:首次写入不可覆盖、同轮去重、失败不中断、`live_since` 实时/回填标记、`backfill` 的 dry-run 与 limit;
|
||||
- 时长效率:`duration` 缺失/非正数、短于门槛、未满成熟窗口的排除,EB 收缩边界(除零、负先验)。
|
||||
|
||||
只有当标准库测试维护成本明显过高时,才考虑通过 `uv add --dev pytest` 引入 pytest。
|
||||
|
||||
@@ -702,6 +729,19 @@ uv run python tests/test_moves.py
|
||||
- `serve --preview` 校验 `preview:seeded=1` 标记,预览页面显示“预览数据”横幅;
|
||||
- 自动化测试见 `tests/test_analytics.py`、`test_preview_seed.py`、`test_web_queries.py`、`test_web_server.py`。
|
||||
|
||||
### 第 9 轮:时长效率榜、粉丝快照与导航拆分 ✅(2026-11-01)
|
||||
|
||||
- 迁移 v4:`video.pages`、`video.up_follower` / `up_follower_at` / `up_follower_backfilled`、`up_profile`;
|
||||
- 收藏夹同步结束时采集缺失 UP 的粉丝数(`relation/stat`,匿名可用);`first_seen >= 运行开始 - 1h` 记为实时,更早的记为回填;
|
||||
- `app.py backfill-followers`:一次性回填历史视频粉丝数,支持 `--limit` / `--dry-run`;
|
||||
- 新增内容效率/互动效率榜与 UP 内容效率(Gamma–Poisson EB 收缩),过滤 < 600 秒与未满 14 天的视频;
|
||||
- `analytics` 配置段:`min_duration_seconds`、`maturity_days`、`min_view_for_efficiency`、`shrink_minutes`;
|
||||
- 主导航拆分:`/videos`(视频)与 `/ups`(UP主)独立;旧 `/rank` 保留兼容;
|
||||
- 新增 `/about` 数据说明页与 `/api/about`;
|
||||
- 卡片精简:列表只保留主指标与互动率,明细移到详情页;
|
||||
- 本地只保留可再生的预览库 `data/preview/app.db`;
|
||||
- 自动化测试新增 `tests/test_up_profile.py`,并扩展 `test_analytics.py`、`test_repository.py`、`test_config.py`、`test_folder_sync.py`、`test_web_queries.py`、`test_web_server.py`、`test_migrations.py`、`test_database.py`、`test_cli.py`。
|
||||
|
||||
### P4:可选部署
|
||||
|
||||
- 反向代理、TLS、远程访问鉴权;
|
||||
|
||||
+51
-12
@@ -1,7 +1,7 @@
|
||||
# 咻咻满 Reaction 视频数据看板 —— 可行性分析与技术路线
|
||||
|
||||
> 状态:**设计定稿;P0(数据底座与收藏夹同步)、P1(每日快照与粉丝追踪)、P2(只读本地看板)、P3(Telegram 与一键加入)已实施**
|
||||
> 最后更新:2026-10-31(第 8 轮:P2 只读看板与预览数据落地)
|
||||
> 状态:**设计定稿;P0(数据底座与收藏夹同步)、P1(每日快照与粉丝追踪)、P2(只读本地看板)、P3(Telegram 与一键加入)已实施;第 9 轮加入时长效率榜、UP 粉丝快照与导航拆分**
|
||||
> 最后更新:2026-11-01(第 9 轮:时长效率榜、粉丝快照采集、视频/UP 导航拆分与数据说明页)
|
||||
> B 站探测均为只读(GET),尚未调用 `fav/resource/deal`、`fav/resource/sort`
|
||||
|
||||
---
|
||||
@@ -517,6 +517,15 @@ CREATE TABLE fav_action (
|
||||
CREATE TABLE kv (k TEXT PRIMARY KEY, v TEXT);
|
||||
```
|
||||
|
||||
**第 9 轮新增(schema v4,已迁移)**
|
||||
|
||||
- `video.pages`:分 P 数(来自 `infos` 的 `page`),只用于详情展示与包装诊断,不参与排序;
|
||||
- `video.up_follower` / `up_follower_at` / `up_follower_backfilled`:视频**入库时**的 UP 粉丝数快照;
|
||||
- `up_profile(mid, name, follower_first, following_first, first_captured_at, follower_latest, last_refreshed)`:每个 UP 的首次/最近粉丝数。`follower_first` 不可被覆盖;
|
||||
- 采集:收藏夹同步结束时对仍缺粉丝数的 UP 调一次 `relation/stat`(匿名可用);`first_seen >= 本次运行开始前 1 小时` 的视频记为实时采集,更早的记为回填;
|
||||
- 回填:`python app.py backfill-followers [--limit N] [--dry-run]`,只补 `up_follower IS NULL` 的追踪视频;
|
||||
- 基于粉丝数的榜单暂不实现,本轮只保证数据从现在起不再缺失。
|
||||
|
||||
**要点**
|
||||
|
||||
- `status` 是核心状态机:
|
||||
@@ -661,6 +670,25 @@ fan_delta_cum = follower(d) - follower(首日)
|
||||
- 缺失日不插值,曲线断开并标注;
|
||||
- 首日没有前值,第一条增量从第 2 天开始。
|
||||
|
||||
### 8.5 时长效率与 UP 内容效率(第 9 轮)
|
||||
|
||||
Reaction 视频时长差异极大(100~336 分钟),而播放是累计计数;若不加时长分母,长视频会天然占优,短视频/切片则天然吃亏。因此新增与时长相关的口径:
|
||||
|
||||
```
|
||||
内容小时 = duration / 3600 # 多 P 的 duration 已是各 P 之和
|
||||
内容效率 = view / 内容小时
|
||||
互动效率 = (like + coin + favorite) / 内容小时
|
||||
UP 内容效率 = EB 收缩后的 Σview / Σ内容小时
|
||||
```
|
||||
|
||||
- 分母只用总时长,**不用分 P 数**:B 站播放记在 bvid 上,`view / pages` 没有统计含义;`pages` 仅用于详情展示与包装诊断;
|
||||
- 效率榜只统计 `duration >= analytics.min_duration_seconds`(默认 600 秒)且发布满 `analytics.maturity_days`(默认 14 天)的视频;不足者标注"样本不足";
|
||||
- **不用无界年龄项**:reaction 视频约两周进入平台期,`log(age)` 会系统性惩罚老视频,故采用"成熟窗口筛选"而非年龄回归;
|
||||
- `duration` 为空或 ≤ 0(通常只在失效视频出现)不进入效率榜,不插补;
|
||||
- UP 效率用 Gamma–Poisson 经验贝叶斯:`rate = (Σview + κ·μ₀) / (Σ内容分钟 + κ)`,`μ₀` 为全库播放/分钟,`κ` 自适应取全库 UP 总内容分钟中位数(配置 `analytics.shrink_minutes` 可覆盖,缺省回退 120 分钟);
|
||||
- 视频榜默认 Tab 为内容效率,原始播放榜保留;互动单项只保留播放/投币/收藏/评论,点赞、弹幕、转发并入"互动";
|
||||
- **UP 榜的"视频数"与"总时长"并列展示、分别可排序,不合成单一产出分**(两者高度共线,加权求和的权重是任意的)。
|
||||
|
||||
---
|
||||
|
||||
## 9. 看板
|
||||
@@ -670,9 +698,11 @@ fan_delta_cum = follower(d) - follower(首日)
|
||||
| 页面 | 内容 |
|
||||
|---|---|
|
||||
| 首页 | 最新动态优先:今日增量、最新入库、最近发布、增长动态、热度速览、收藏夹容量、采集状态 |
|
||||
| 榜单 | Tab:综合热度/播放/点赞/投币/收藏/转发/评论/弹幕/互动率/播放增量/播放增速;视频与 UP 范围切换;筛选与搜索 |
|
||||
| 视频详情 | 元数据 + 七项指标 + 单指标趋势(7/30/90/全部)+ 同 UP 对比 + 快照表(含失败标记) |
|
||||
| UP 页 | 该 UP 全部视频、聚合趋势、单视频对比、平均互动率 |
|
||||
| **视频** | Tab:内容效率/综合热度/播放/投币/收藏/评论/互动率/播放增量/播放增速;筛选与搜索 |
|
||||
| **UP主** | 独立入口;列:视频数、总时长、总播放、播放·小时、互动·小时等,可分别排序 |
|
||||
| 数据说明 | 数据来源与更新节奏、三个时间概念、指标公式、时长/成熟窗口筛选、粉丝快照覆盖与已知局限;数值由 `/api/about` 动态读取当前配置 |
|
||||
| 视频详情 | 元数据 + 分 P 数 + 七项指标 + 内容/互动效率 + 入库时粉丝数 + 单指标趋势 + 同 UP 对比 + 快照表 |
|
||||
| UP 页 | 该 UP 全部视频、聚合趋势、单视频对比、总时长/播放·小时、入库时与当前粉丝数 |
|
||||
| **粉丝页** | 咻咻满粉丝数曲线 + 每日/7 日净增 + 累计增长(标注起始日期)+ 最近 14 天记录;支持 7/30/90/全部与自选起止日期,范围不超过一年按日绘制,超过一年按每月峰值日期绘制;只画粉丝,不叠加视频数据 |
|
||||
| **候选池** | 候选、得分、通知时间、剩余 TTL;只读展示,操作指向 Telegram/CLI |
|
||||
| **系统状态** | 最近任务、采集成功率、收藏夹同步时间、下次任务、备份、鉴权、黑名单 |
|
||||
@@ -819,12 +849,21 @@ storage:SQLite WAL,单写线程
|
||||
|
||||
## 14. 下一步
|
||||
|
||||
P0、P1、P2、P3 已实施。P2 交付了只读本地看板与可重复生成的 7 天预览数据:
|
||||
P0、P1、P2、P3 与第 9 轮已实施;P2 交付了只读本地看板与可重复生成的 7 天预览数据。
|
||||
|
||||
1. 首页、榜单、视频/UP 详情、粉丝曲线、候选池和系统状态页面;
|
||||
2. 原生 ES Module + 本地 ECharts,本机默认绑定 `127.0.0.1:8080`;
|
||||
3. 查询、热度、增长和互动率全部在服务端计算,前端只渲染;
|
||||
4. Web 不提供业务写操作,数据管理继续通过 Telegram/CLI/数据库;
|
||||
5. P3 的真实 `deal` / `sort` 待用户点击 Telegram 按钮或授权测试视频后补充验证记录。
|
||||
第 9 轮(2026-11-01)交付:
|
||||
|
||||
> P4(容器化 + 反代)继续保持可选。
|
||||
1. schema v4:`video.pages`、`video.up_follower*`、`up_profile`;
|
||||
2. 入库时采集 UP 粉丝快照 + `python app.py backfill-followers` 历史回填(基于粉丝数的榜单暂不做);
|
||||
3. 时长效率榜(内容效率/互动效率)与 UP 内容效率(EB 收缩),过滤 < 600 秒与未满 14 天的视频;
|
||||
4. 主导航拆分:「榜单」→「视频」+「UP主」,两者独立页面;新增「数据说明」页(`/about` + `/api/about`);
|
||||
5. 列表精简:卡片只保留主指标 + 互动率,七项明细与分 P、粉丝快照移到详情页。
|
||||
|
||||
仍待处理:
|
||||
|
||||
1. 真实 `deal` / `sort` 与 Telegram 按钮回调的补充验证记录;
|
||||
2. 基于粉丝数的"破圈"维度(播放/入库时粉丝数、粉丝分段、UP 中位数)——数据已就绪,榜单未实现;
|
||||
3. P4(容器化 + 反代)继续保持可选。
|
||||
|
||||
> 本地数据:第 9 轮起本地只保留可再生的预览库 `data/preview/app.db`(`tools/seed_preview_db.py` 生成),
|
||||
> 原 `data/app.db` 真实副本已删除;需要重新生成或恢复时,用 `--source data/backup/app-local-before-reseed-20261101.db`。
|
||||
Reference in new issue
Block a user