|
|
@@ -0,0 +1,116 @@
|
|
|
+# 小红书作品(笔记)每日统计数据导入逻辑与字段映射
|
|
|
+
|
|
|
+## 接口信息
|
|
|
+
|
|
|
+- **接口**:`GET https://creator.xiaohongshu.com/api/galaxy/creator/datacenter/note/base?note_id={noteId}`
|
|
|
+- **页面**:`https://creator.xiaohongshu.com/statistics/note-detail?noteId={noteId}`
|
|
|
+- **数据来源**:返回体中的 `data.day`(日维度趋势数据)
|
|
|
+
|
|
|
+## 导入流程
|
|
|
+
|
|
|
+1. **遍历账号下所有作品**:从 `works` 表查询该账号的所有小红书作品
|
|
|
+2. **访问笔记详情页**:打开 `statistics/note-detail?noteId={noteId}`
|
|
|
+3. **监听接口响应**:等待 `note/base` 接口响应(超时 30 秒)
|
|
|
+4. **解析数据**:
|
|
|
+ - 提取 `data.day` 下的各 `*_list` 数组
|
|
|
+ - 按 `date`(毫秒时间戳)合并为「按日一条」的数据
|
|
|
+ - 使用 `getChinaDateFromTimestamp` 将时间戳转成中国时区日期
|
|
|
+5. **过滤时间范围**:默认只保留「作品发布后 14 天内」的数据(`publishTime + 13 天`)
|
|
|
+6. **批量写入**:调用 `WorkDayStatisticsService.saveStatisticsForDateBatch` 写入 `work_day_statistics` 表
|
|
|
+
|
|
|
+## 字段映射表
|
|
|
+
|
|
|
+### 数值型字段(每日增量,累加)
|
|
|
+
|
|
|
+| work_day_statistics 字段 | data.day 来源 | 说明 |
|
|
|
+|--------------------------|---------------|------|
|
|
|
+| record_date | 各 list 项的 `date`(毫秒 → 中国时区当天 0 点) | 按日期合并多条 list |
|
|
|
+| play_count | view_list[].count | 播放(阅读)量 |
|
|
|
+| exposure_count | imp_list[].count | 曝光量/展现量 |
|
|
|
+| like_count | like_list[].count | 点赞量 |
|
|
|
+| comment_count | comment_list[].count | 评论量 |
|
|
|
+| share_count | share_list[].count | 分享量 |
|
|
|
+| collect_count | collect_list[].count | 收藏量 |
|
|
|
+| fans_increase | rise_fans_list[].count | 涨粉数 |
|
|
|
+
|
|
|
+### 比率类字段(百分比字符串,使用 `coun` 字段)
|
|
|
+
|
|
|
+| work_day_statistics 字段 | data.day 来源 | 格式 |
|
|
|
+|--------------------------|---------------|------|
|
|
|
+| cover_click_rate | cover_click_rate_list[].coun | "14%" 或 "0" |
|
|
|
+| two_second_exit_rate | exit_view2s_list[].coun | "5%" 或 "0" |
|
|
|
+| completion_rate | finish_list[].coun | "15%" 或 "0" |
|
|
|
+
|
|
|
+**说明**:比率类字段使用 `item.coun`(不是 `count`),如果值为 0 则存 "0",否则存 `${n}%"`。
|
|
|
+
|
|
|
+### 时长/数值字符串字段(不加 %)
|
|
|
+
|
|
|
+| work_day_statistics 字段 | data.day 来源 | 格式 |
|
|
|
+|--------------------------|---------------|------|
|
|
|
+| avg_watch_duration | view_time_list[].count_with_double 或 count | 保留两位小数的字符串,如 "12.34" |
|
|
|
+
|
|
|
+**说明**:优先使用 `count_with_double`,否则用 `count`,保留两位小数(四舍五入)。
|
|
|
+
|
|
|
+## 数据汇总(同步到 works 表)
|
|
|
+
|
|
|
+除了日统计,还会将 `data` 顶层的汇总指标同步到 `works` 表的 `yesterday*` 字段:
|
|
|
+
|
|
|
+| works 字段 | data 来源 | 说明 |
|
|
|
+|------------|-----------|------|
|
|
|
+| yesterday_play_count | view_count | 总播放数 |
|
|
|
+| yesterday_like_count | like_count | 总点赞数 |
|
|
|
+| yesterday_comment_count | comment_count | 总评论数 |
|
|
|
+| yesterday_share_count | share_count | 总分享数 |
|
|
|
+| yesterday_collect_count | collect_count | 总收藏数 |
|
|
|
+| yesterday_fans_increase | rise_fans_count | 总涨粉数 |
|
|
|
+| yesterday_exposure_count | impl_count | 总曝光数 |
|
|
|
+| yesterday_cover_click_rate | cover_click_rate | 封面点击率(格式化为 "14%") |
|
|
|
+| yesterday_avg_watch_duration | view_time_avg_with_double 或 view_time_avg | 平均观看时长(保留两位小数) |
|
|
|
+| yesterday_completion_rate | full_view_rate | 完播率(格式化为 "15%") |
|
|
|
+| yesterday_two_second_exit_rate | exit_view2s_rate | 2秒退出率(格式化为 "5%") |
|
|
|
+
|
|
|
+## 时区处理
|
|
|
+
|
|
|
+- **接口返回的 `date`**:中国时区(Asia/Shanghai)该日 0 点的 UTC 时间戳
|
|
|
+- **解析方式**:使用 `getChinaDateFromTimestamp(ts)` 函数,通过 `Intl.DateTimeFormat` 按中国时区解析年月日
|
|
|
+- **存储**:`record_date` 字段存为 DATE 类型,代表中国时区的日历日
|
|
|
+
|
|
|
+## 时间范围限制
|
|
|
+
|
|
|
+- **默认**:只保留「作品发布后 14 天内」的数据
|
|
|
+ - 计算方式:`publishTime` 的当天 + 13 天 = 共 14 天
|
|
|
+ - 例如:2026-01-01 发布,则保留 2026-01-01 至 2026-01-14 的数据
|
|
|
+- **首批补数据**:可通过 `ignorePublishTimeLimit: true` 选项跳过此限制
|
|
|
+
|
|
|
+## 错误处理
|
|
|
+
|
|
|
+- **登录失效**:检测到跳转到 `login` 页面时,抛出 `XhsLoginExpiredError`
|
|
|
+ - 首次失效:尝试刷新账号 cookie
|
|
|
+ - 刷新成功:用新 cookie 重试一次
|
|
|
+ - 刷新失败或重试仍失效:标记账号为 `expired` 状态
|
|
|
+- **接口超时**:30 秒内未捕获到响应则跳过该作品,继续处理下一个
|
|
|
+- **数据缺失**:`data.day` 为空或不存在时返回空数组,不写入
|
|
|
+
|
|
|
+## 调用方式
|
|
|
+
|
|
|
+### 定时任务(批量同步所有账号)
|
|
|
+
|
|
|
+```typescript
|
|
|
+await XiaohongshuWorkNoteStatisticsImportService.runDailyImport();
|
|
|
+```
|
|
|
+
|
|
|
+### 单账号同步
|
|
|
+
|
|
|
+```typescript
|
|
|
+const svc = new XiaohongshuWorkNoteStatisticsImportService();
|
|
|
+await svc.importAccountWorksStatistics(account);
|
|
|
+```
|
|
|
+
|
|
|
+### 指定作品(首批补数据)
|
|
|
+
|
|
|
+```typescript
|
|
|
+await svc.importAccountWorksStatistics(account, false, {
|
|
|
+ workIdFilter: [workId1, workId2],
|
|
|
+ ignorePublishTimeLimit: true
|
|
|
+});
|
|
|
+```
|