#!/usr/bin/env node /** * 只跑 TikTok · 合并结果到已有 data/jiangzhong-*-voc.json * 用法:node scripts/tools/collect-tiktok-only.js [liver|probiotic|monkey|all] */ const fs = require('fs'); const path = require('path'); const { collectTikTokForProduct } = require('./collect-tiktok'); const PRODUCTS = [ { id: 'liver', name: '江中肝纯片', keywords_en: ['milk thistle', 'liver support supplement', 'liver cleanse detox', 'silymarin'], }, { id: 'probiotic', name: '儿童乳酸菌素片', keywords_en: ['kids probiotics', 'children probiotics gummy', 'probiotics gummies for kids', 'childrens digestive supplement'], }, { id: 'monkey', name: '江中猴菇饮', keywords_en: ['lions mane mushroom supplement', 'lion mane mushroom', 'stomach gut health supplement', 'lions mane gummies'], }, ]; async function main() { const target = process.argv[2] || 'all'; const picks = target === 'all' ? PRODUCTS : PRODUCTS.filter((p) => p.id === target); if (!picks.length) { console.error(`❌ 未知 product: ${target}`); process.exit(1); } console.log('╔══════════════════════════════════════════════════════════╗'); console.log('║ TikTok VOC 采集(Amazon 的内容端对标) ║'); console.log('╚══════════════════════════════════════════════════════════╝'); console.log(`🎯 目标:${picks.map((p) => p.id).join(', ')}`); for (const p of picks) { const jsonPath = path.resolve(__dirname, '..', '..', 'data', `jiangzhong-${p.id}-voc.json`); if (!fs.existsSync(jsonPath)) { console.error(`❌ ${jsonPath} 不存在,请先跑全量采集`); continue; } console.log(`\n━━━━ [${p.id}] ${p.name} ━━━━`); const t0 = Date.now(); const tt = await collectTikTokForProduct(p); const elapsed = ((Date.now() - t0) / 1000).toFixed(1); const data = JSON.parse(fs.readFileSync(jsonPath, 'utf-8')); data.tiktok = tt; data._meta = data._meta || {}; data._meta.tiktok_updated_at = new Date().toISOString(); fs.writeFileSync(jsonPath, JSON.stringify(data, null, 2)); const vcount = tt.merged_videos?.length || 0; const acount = tt.top_authors?.length || 0; const profiles = Object.keys(tt.author_profiles || {}).length; const postsAll = Object.values(tt.author_posts || {}).reduce((s, a) => s + (a?.length || 0), 0); const ccount = Object.values(tt.top_comments_by_video || {}).reduce((s, a) => s + (a?.length || 0), 0); const catUsers = Object.values(tt.category_users || {}).reduce((s, a) => s + (a?.length || 0), 0); console.log(`\n✅ [${p.id}] 完成 (${elapsed}s)`); console.log(` · 视频 ${vcount} · 评论 ${ccount}`); console.log(` · Top 作者 ${acount} · profiles ${profiles} · 作品 ${postsAll}`); console.log(` · 品类用户 ${catUsers}`); } } main().catch((e) => { console.error('❌', e); process.exit(1); });