# 小红书作品(笔记)每日统计数据导入逻辑与字段映射 ## 接口信息 - **接口**:`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 }); ```