#!/usr/bin/env node // 扫描 data/probe-ultimate/*.json,打印每个端点的 data 结构核心要点 const fs = require('fs'); const path = require('path'); const DIR = path.join('data', 'probe-ultimate'); const files = fs.readdirSync(DIR).filter((f) => f.endsWith('.json') && f !== '_overview.json').sort(); function inspect(name, json) { const sj = json.sampleJson || {}; const d = sj.data; if (!d) return { _nodata: true }; // TikHub 常见二级嵌套 data.data const inner = d.data || d; if (!inner || typeof inner !== 'object') return { _notobj: typeof inner }; const keys = Object.keys(inner); const report = { topLevelKeys: keys }; // 最常见:objs / user_list / data / list / items for (const arrKey of ['objs', 'user_list', 'data', 'list', 'items', 'hot_search_word_list', 'word_list', 'account_list', 'aweme_list']) { if (Array.isArray(inner[arrKey])) { const arr = inner[arrKey]; report.arrKey = arrKey; report.len = arr.length; report.firstItemKeys = arr[0] ? Object.keys(arr[0]).slice(0, 12) : []; report.firstItemSample = arr[0] ? JSON.stringify(arr[0]).slice(0, 400) : null; break; } } return report; } const summary = {}; for (const f of files) { const p = path.join(DIR, f); const j = JSON.parse(fs.readFileSync(p, 'utf-8')); if (j.status !== 200) { summary[j.name] = { status: j.status, ok: false }; continue; } summary[j.name] = { status: 200, path: j.path, body: j.body, params: j.params, ...inspect(j.name, j) }; } // 分组打印 const groups = { 'A-douyin-billboard': ['fetch_hot_total_video_list', 'fetch_hot_total_topic_list', 'fetch_hot_total_search_list', 'fetch_hot_total_hot_word_list', 'fetch_hot_total_high_fan_list', 'fetch_hot_total_high_like_list', 'fetch_hot_total_high_play_list', 'fetch_hot_total_high_topic_list', 'fetch_hot_total_high_search_list', 'fetch_hot_account_list', 'fetch_hot_calendar_list', 'web_fetch_hot_search_result'], 'B-tiktok-ads': ['get_keyword_list', 'get_keyword_details', 'get_keyword_insights', 'get_related_keywords', 'get_top_products', 'get_top_ads_spotlight', 'get_creator_list', 'search_creators'], }; for (const [g, names] of Object.entries(groups)) { console.log(`\n=========== ${g} ===========`); for (const n of names) { const s = summary[n]; if (!s) { console.log(` ${n}: NOT FOUND`); continue; } console.log(`\n ▸ ${n}`); console.log(` path: ${s.path}`); if (s.status !== 200) { console.log(` status: ${s.status} ✗`); continue; } console.log(` topLevelKeys: ${JSON.stringify(s.topLevelKeys)}`); if (s.arrKey) { console.log(` arrKey=${s.arrKey} len=${s.len}`); console.log(` firstItemKeys: ${JSON.stringify(s.firstItemKeys)}`); console.log(` firstItemSample: ${s.firstItemSample}`); } else { console.log(` (no array list found at top level)`); } } }