collect-tiktok-only.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/env node
  2. /**
  3. * 只跑 TikTok · 合并结果到已有 data/jiangzhong-*-voc.json
  4. * 用法:node scripts/tools/collect-tiktok-only.js [liver|probiotic|monkey|all]
  5. */
  6. const fs = require('fs');
  7. const path = require('path');
  8. const { collectTikTokForProduct } = require('./collect-tiktok');
  9. const PRODUCTS = [
  10. {
  11. id: 'liver',
  12. name: '江中肝纯片',
  13. keywords_en: ['milk thistle', 'liver support supplement', 'liver cleanse detox', 'silymarin'],
  14. },
  15. {
  16. id: 'probiotic',
  17. name: '儿童乳酸菌素片',
  18. keywords_en: ['kids probiotics', 'children probiotics gummy', 'probiotics gummies for kids', 'childrens digestive supplement'],
  19. },
  20. {
  21. id: 'monkey',
  22. name: '江中猴菇饮',
  23. keywords_en: ['lions mane mushroom supplement', 'lion mane mushroom', 'stomach gut health supplement', 'lions mane gummies'],
  24. },
  25. ];
  26. async function main() {
  27. const target = process.argv[2] || 'all';
  28. const picks = target === 'all' ? PRODUCTS : PRODUCTS.filter((p) => p.id === target);
  29. if (!picks.length) {
  30. console.error(`❌ 未知 product: ${target}`);
  31. process.exit(1);
  32. }
  33. console.log('╔══════════════════════════════════════════════════════════╗');
  34. console.log('║ TikTok VOC 采集(Amazon 的内容端对标) ║');
  35. console.log('╚══════════════════════════════════════════════════════════╝');
  36. console.log(`🎯 目标:${picks.map((p) => p.id).join(', ')}`);
  37. for (const p of picks) {
  38. const jsonPath = path.resolve(__dirname, '..', '..', 'data', `jiangzhong-${p.id}-voc.json`);
  39. if (!fs.existsSync(jsonPath)) {
  40. console.error(`❌ ${jsonPath} 不存在,请先跑全量采集`);
  41. continue;
  42. }
  43. console.log(`\n━━━━ [${p.id}] ${p.name} ━━━━`);
  44. const t0 = Date.now();
  45. const tt = await collectTikTokForProduct(p);
  46. const elapsed = ((Date.now() - t0) / 1000).toFixed(1);
  47. const data = JSON.parse(fs.readFileSync(jsonPath, 'utf-8'));
  48. data.tiktok = tt;
  49. data._meta = data._meta || {};
  50. data._meta.tiktok_updated_at = new Date().toISOString();
  51. fs.writeFileSync(jsonPath, JSON.stringify(data, null, 2));
  52. const vcount = tt.merged_videos?.length || 0;
  53. const acount = tt.top_authors?.length || 0;
  54. const profiles = Object.keys(tt.author_profiles || {}).length;
  55. const postsAll = Object.values(tt.author_posts || {}).reduce((s, a) => s + (a?.length || 0), 0);
  56. const ccount = Object.values(tt.top_comments_by_video || {}).reduce((s, a) => s + (a?.length || 0), 0);
  57. const catUsers = Object.values(tt.category_users || {}).reduce((s, a) => s + (a?.length || 0), 0);
  58. console.log(`\n✅ [${p.id}] 完成 (${elapsed}s)`);
  59. console.log(` · 视频 ${vcount} · 评论 ${ccount}`);
  60. console.log(` · Top 作者 ${acount} · profiles ${profiles} · 作品 ${postsAll}`);
  61. console.log(` · 品类用户 ${catUsers}`);
  62. }
  63. }
  64. main().catch((e) => { console.error('❌', e); process.exit(1); });