小红书笔记评论 API 接口深度解析(带全套 JSON 示例・技术实战版)
从接口路径到异常处理,再到结构化入库,本文对小红书评论 API 进行了全面拆解。无论你是从事舆情监控、竞品分析,还是仅需批量拉取评论做数据统计,这篇文章都能帮你节省大量试错时间。
一、接口基础说明
1. 接口基础信息
接口路径为
/api/v1/note/comment/list,这是小红书开放平台的标准评论接口。

请求方式为 POST,鉴权需在 Header 中添加
Authorization: Bearer access_token,采用 OAuth2.0 令牌鉴权机制。分页规则较为特殊——使用游标 cursor 分页,传统的页码 page 已不再支持。首次请求时 cursor 传入空字符串,后续页使用上一页返回的 cursor 值。
sort 参数支持
hot(按热度排序)或
time(按时间倒序),
page_size 单页可设置 1~50 条。官方 QPS 限制为 5 次/秒,调用频率过高将被限流。
下面是一个请求入参的 JSON 示例:
```json
{
"note_id": "649c46ab000000002702ad36",
"cursor": "",
"page_size": 20,
"sort": "hot",
"need_sub_comment": true
}
```
具体参数说明见下表:
| 参数 | 必填 | 说明 |
| note_id | 是 | 笔记唯一标识符(32 位字符串,可从笔记链接中提取) |
| cursor | 否 | 分页游标,空字符串表示第一页 |
| page_size | 否 | 每页评论数量,默认 20 条 |
| sort | 否 | hot 表示按热度排序,time 表示按时间倒序 |
| need_sub_comment | 否 | true 表示同时返回楼中楼子评论 |
二、接口原生返回完整 JSON(真实脱敏样例)
下面展示接口原生返回的 JSON 结构。其层级较深,子评论嵌套在内部,时间字段采用 Unix 时间戳,用户信息嵌入在评论对象中——若想直接存入数据库或进行数据分析,几乎不可行。
```json
{
"code": 200,
"msg": "success",
"request_id": "req_987654321abc",
"data": {
"note_id": "649c46ab000000002702ad36",
"total_comment": 1256,
"cursor": "crs_20260603_001",
"has_more": true,
"comments": [
{
"comment_id": "com_1122334455",
"content": "油皮亲妈!上脸清爽不闷痘,已经囤两瓶啦?",
"create_time": 1744289620,
"like_count": 326,
"reply_count": 18,
"is_top": true,
"user": {
"user_id": "u_589abc789",
"nickname": "油痘肌避雷君",
"a vatar": "https://sns-a vatar-qc.xhscdn.com/a vatar/abc123.jpg",
"is_creator": false
},
"sub_comments": [
{
"comment_id": "sub_998877",
"content": "想问多少钱入手的?",
"create_time": 1744290120,
"like_count": 12,
"reply_user_id": "u_589abc789",
"user": {
"user_id": "u_321def654",
"nickname": "奶茶不加冰",
"a vatar": "https://sns-a vatar-qc.xhscdn.com/a vatar/def456.jpg"
}
}
]
},
{
"comment_id": "com_5566778899",
"content": "@小丸子 敏感肌能用吗?",
"create_time": 1744291200,
"like_count": 45,
"reply_count": 0,
"is_top": false,
"user": {
"user_id": "u_789ghi123",
"nickname": "护肤小白日常",
"a vatar": "https://sns-a vatar-qc.xhscdn.com/a vatar/ghi789.jpg",
"is_creator": false
},
"sub_comments": []
}
]
}
}
```
顶层字段释义
-
code:200 表示请求成功;401 表示 token 已失效;403 表示权限不足;429 表示接口被限流
-
request_id:请求唯一标识,用于接口异常排查日志
-
data.total_comment:笔记全量评论总数
-
data.has_more:true 表示存在下一页数据,可继续游标翻页
三、原生 JSON 痛点
原生 JSON 存在以下几个明显的痛点:
- 时间字段为 Unix 时间戳,业务层需手动格式化为
yyyy-MM-dd HH:mm:ss;
- 主评论和子评论嵌套在一起,子评论归属关系不直观,解析时容易绕晕;
- 用户信息内嵌在 comment 对象里,字段分散,不利于分表存储(评论表 vs 用户表);
- 置顶标识
is_top 零散在各条评论中,想批量筛选出所有置顶评论需要额外遍历;
- @关联用户没有结构化字段,@文本全混在 content 里,提取关键词得自己挖。
四、结构化解析后标准 JSON(落地入库模型)
针对上述问题,最直接的解决方案是对原生 JSON 进行结构化解析,将其拆分为扁平化格式。将主评论与子评论分离,时间格式统一,用户信息整合到独立对象中。这样生成的 JSON 可直接存入 MySQL 或 Elasticsearch,用于舆情分析、竞品评论统计等场景十分便捷。
```json
{
"note_id": "649c46ab000000002702ad36",
"total_comment": 1256,
"next_cursor": "crs_20260603_001",
"has_more": true,
"main_comments": [
{
"comment_id": "com_1122334455",
"comment_type": "main",
"content": "油皮亲妈!上脸清爽不闷痘,已经囤两瓶啦?",
"create_time_stamp": 1744289620,
"create_time": "2025-06-10 15:53:40",
"like_count": 326,
"reply_count": 18,
"is_top": true,
"user_info": {
"user_id": "u_589abc789",
"nickname": "油痘肌避雷君",
"a vatar": "https://sns-a vatar-qc.xhscdn.com/a vatar/abc123.jpg"
},
"sub_comments": [
{
"comment_id": "sub_998877",
"comment_type": "sub",
"parent_comment_id": "com_1122334455",
"content": "想问多少钱入手的?",
"create_time_stamp": 1744290120,
"create_time": "2025-06-10 16:02:00",
"like_count": 12,
"reply_target_uid": "u_589abc789",
"user_info": {
"user_id": "u_321def654",
"nickname": "奶茶不加冰",
"a vatar": "https://sns-a vatar-qc.xhscdn.com/a vatar/def456.jpg"
}
}
]
},
{
"comment_id": "com_5566778899",
"comment_type": "main",
"content": "@小丸子 敏感肌能用吗?",
"create_time_stamp": 1744291200,
"create_time": "2025-06-10 16:13:20",
"like_count": 45,
"reply_count": 0,
"is_top": false,
"user_info": {
"user_id": "u_789ghi123",
"nickname": "护肤小白日常",
"a vatar": "https://sns-a vatar-qc.xhscdn.com/a vatar/ghi789.jpg"
},
"sub_comments": []
}
]
}
```
五、核心解析实战要点
在实际解析过程中,有几个关键细节需要注意:
- **时间格式化**:将
create_time 时间戳统一转换为标准日期字符串,便于后续按天或按月统计评论数量。
- **父子评论绑定**:为子评论新增
parent_comment_id 字段,直接关联所属主评论的 ID,数据库内关联查询一步到位。
- **用户信息剥离**:将用户信息封装为
user_info 对象,方便后续与用户画像库关联。
- **空值容错**:
sub_comments 在没有回复时默认返回空数组,避免数组遍历时抛出空指针异常。
- **分页闭环**:每次请求保存返回的
cursor,循环遍历直到
has_more 为 false,即可拉取笔记下全部评论。
六、接口异常返回 JSON 示例(错误处理参考)
接口调用难免遇到异常情况,如 token 过期或限流是常见问题。以下两个示例展示了最常见的异常场景:
```json
{
"code": 401,
"msg": "access_token已过期,请重新授权",
"request_id": "req_err_123456",
"data": {}
}
```
```json
{
"code": 429,
"msg": "接口调用超限,限流冷却10s",
"request_id": "req_limit_789",
"data": {}
}
```
七、落地业务场景
解析后的评论数据可应用于多种实际业务场景:
- **品牌舆情监控**:抓取评论关键词,统计好评与差评占比,分析用户对产品的真实痛点。
- **竞品数据分析**:对标同品类笔记的评论量、互动率,测算竞品的种草热度。
- **用户问答收集**:筛选出带有价格、使用方法等常见问题的评论,整理成 FAQ 知识库。
八、精简 Python 解析代码(配套实战)
最后,提供一段可直接运行的 Python 解析代码,核心逻辑是对原生 JSON 进行扁平化转换,已添加注释,稍作修改即可使用。
```python
import time
def parse_xhs_comment(raw_json):
res = {}
resp_data = raw_json.get("data", {})
res["note_id"] = resp_data.get("note_id")
res["total_comment"] = resp_data.get("total_comment",0)
res["next_cursor"] = resp_data.get("cursor","")
res["has_more"] = resp_data.get("has_more",False)
main_list = []
#遍历主评论
for item in resp_data.get("comments",[]):
main = {
"comment_id":item["comment_id"],
"comment_type":"main",
"content":item["content"],
"create_time_stamp":item["create_time"],
"create_time":time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(item["create_time"])),
"like_count":item["like_count"],
"reply_count":item["reply_count"],
"is_top":item["is_top"],
"user_info":item["user"],
"sub_comments":[]
}
#解析子评论
subs = []
for sub in item.get("sub_comments",[]):
sub_item = {
"comment_id":sub["comment_id"],
"comment_type":"sub",
"parent_comment_id":main["comment_id"],
"content":sub["content"],
"create_time_stamp":sub["create_time"],
"create_time":time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(sub["create_time"])),
"like_count":sub["like_count"],
"reply_target_uid":sub.get("reply_user_id",""),
"user_info":sub["user"]
}
subs.append(sub_item)
main["sub_comments"] = subs
main_list.append(main)
res["main_comments"] = main_list
return res