inspect-voc-data.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #!/usr/bin/env node
  2. /** 快速查看 VOC JSON 数据结构 */
  3. const fs = require('fs');
  4. const path = require('path');
  5. const files = ['jiangzhong-liver-voc.json', 'jiangzhong-probiotic-voc.json', 'jiangzhong-monkey-voc.json'];
  6. for (const f of files) {
  7. const full = path.join('data', f);
  8. if (!fs.existsSync(full)) continue;
  9. const j = JSON.parse(fs.readFileSync(full, 'utf-8'));
  10. console.log('');
  11. console.log('=========================================================');
  12. console.log(` ${j.product} (${j.category})`);
  13. console.log('=========================================================');
  14. // --- XHS 诊断 ---
  15. console.log('\n📕 小红书:');
  16. for (const kw of Object.keys(j.xiaohongshu?.by_keyword || {})) {
  17. const d = j.xiaohongshu.by_keyword[kw];
  18. const nNotes = d.notes?.length || 0;
  19. const nCommentNotes = Object.keys(d.comments || {}).length;
  20. const totalComments = Object.values(d.comments || {}).reduce((s, arr) => s + (arr?.length || 0), 0);
  21. const nUsers = Object.keys(d.users || {}).length;
  22. console.log(` "${kw}": ${nNotes} 笔记, ${nCommentNotes} 笔记抓了评论 (合计 ${totalComments} 条), ${nUsers} 作者`);
  23. const tops = (d.notes || []).slice(0, 3).map((n) => `[${n.liked_count || 0}👍 ${n.comments_count || 0}💬] ${n.title?.slice(0, 50)}`);
  24. tops.forEach((t) => console.log(` • ${t}`));
  25. }
  26. // --- 抖音诊断 ---
  27. console.log('\n🎬 抖音:');
  28. for (const kw of Object.keys(j.douyin?.by_keyword || {})) {
  29. const d = j.douyin.by_keyword[kw];
  30. console.log(` "${kw}": videos=${d.videos?.length || 0}, comments_groups=${Object.keys(d.comments || {}).length}`);
  31. if (d._error) console.log(` ❌ error: ${JSON.stringify(d._error).slice(0, 200)}`);
  32. if (d.videos?.length === 0) {
  33. // Dump a sample key of what we actually got
  34. console.log(` raw keys: ${Object.keys(d).join(', ')}`);
  35. }
  36. }
  37. // --- Sorftime 诊断 ---
  38. console.log('\n🌎 Sorftime:');
  39. for (const kw of Object.keys(j.sorftime?.by_keyword || {})) {
  40. const d = j.sorftime.by_keyword[kw];
  41. console.log(` "${kw}":`);
  42. console.log(` keyword_info keys: ${Object.keys(d.keyword_info || {}).join(', ').slice(0, 200) || '(empty)'}`);
  43. // top_products typical shape: {Data:{Items:[...]}} or {Items:[...]}
  44. const prods = d.top_products?.Data?.Items || d.top_products?.Items || d.top_products || [];
  45. console.log(` top_products 类型: ${Array.isArray(prods) ? 'Array(' + prods.length + ')' : typeof prods}`);
  46. if (Array.isArray(prods)) {
  47. prods.slice(0, 3).forEach((p) => {
  48. console.log(` • ${p.Brand || '?'} — $${(p.Price / 100).toFixed(2)} — Rank ${p.Rank} — ${(p.Title || '').slice(0, 60)}`);
  49. });
  50. } else if (prods && typeof prods === 'object') {
  51. console.log(` top_products keys: ${Object.keys(prods).join(', ')}`);
  52. }
  53. }
  54. }