频道 6 万条评论导出后,我用 jq 清洗时才发现自己一直在丢字段
上个月我把频道从开通到现在的评论都导了出来,大约 6 万条,存成 NDJSON,每行一条。本来只想统计每月评论数,结果 jq 跑完发现总数比后台显示的少了 400 多条。
先说我当时怎么做的。导出文件每行大概长这样:
{"id":"Ugx...","snippet":{"topLevelComment":{"snippet":{"textDisplay":"...","publishedAt":"2023-04-01T12:00:00Z","authorDisplayName":"..."}},"totalReplyCount":3}}
我想取发布时间和作者,写了:
jq -r '.snippet.topLevelComment.snippet | [.publishedAt, .authorDisplayName] | @tsv' comments.ndjson > out.tsv
然后 wc -l 发现 6 万条变成了 5.96 万。
第一反应是文件有坏行。jq -c . comments.ndjson > /dev/null 确实报了几行 parse error,但只有十几行,对不上。
接着我按 id 去重,发现丢的全是 topLevelComment 里没有 authorDisplayName 的条目——频道被删或者作者注销的评论,这个字段直接不存在。jq 的 @tsv 遇到 null 会输出空字符串,不会报错,但后续 awk 按 tab 切列时,如果整行是 \t,有些行会被误判成只有一列。
问题出在我没检查字段是否存在。改成:
jq -r '(.snippet.topLevelComment.snippet.publishedAt // "") + "\t" + (.snippet.topLevelComment.snippet.authorDisplayName // "__gone__")' comments.ndjson
把缺失作者标记成占位符,再统计就对齐了。
为什么之前没发现:我默认以为导出的每一条都有完整 snippet,但 YouTube 的评论资源在作者账号停用后,authorDisplayName 和 authorProfileImageUrl 会直接缺省,而不是给空串。这个行为不是文档里一眼能看到的,我是拿 id 反查才确认的。
边界在于:如果评论本身被平台移除,整条 topLevelComment 可能都不在,我的脚本只处理了字段缺失,没处理对象缺失。后来加了 if .snippet.topLevelComment then ... else empty end 才稳。另一个坑是 publishedAt 偶尔带毫秒,按字符串排序会错位,得先 fromdateiso8601。
你们导出评论做分析时,是怎么处理作者字段缺失的?是直接丢弃还是单独归类?
0 条评论
还没有评论,写下第一条。