| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #!/usr/bin/env node
- /**
- * 用 POST + JSON 测试 Douyin-Search-API V2 接口
- * 关键线索:不需要 cookie,POST body 参数
- */
- const fs = require('fs');
- const path = require('path');
- const os = require('os');
- const https = require('https');
- const TIKHUB_TOKEN = JSON.parse(
- fs.readFileSync(
- path.join(os.homedir(), '.openclaw', 'skills', 'xiaohongshu-search-notes', 'api-config.json'),
- 'utf-8'
- )
- ).endpoint.headers.Authorization.replace(/^Bearer\s+/, '');
- function post(apiPath, body) {
- return new Promise((resolve) => {
- const payload = JSON.stringify(body);
- const opts = {
- hostname: 'api.tikhub.io',
- path: apiPath,
- method: 'POST',
- headers: {
- Authorization: `Bearer ${TIKHUB_TOKEN}`,
- 'Content-Type': 'application/json',
- 'Content-Length': Buffer.byteLength(payload),
- Accept: 'application/json',
- },
- };
- const req = https.request(opts, (res) => {
- const chunks = [];
- res.on('data', (c) => chunks.push(c));
- res.on('end', () => {
- const text = Buffer.concat(chunks).toString('utf-8');
- try {
- resolve({ status: res.statusCode, json: JSON.parse(text) });
- } catch (e) {
- resolve({ status: res.statusCode, json: { _raw: text.slice(0, 300) } });
- }
- });
- });
- req.on('error', (e) => resolve({ status: 0, json: { _error: e.message } }));
- req.setTimeout(30000, () => { req.destroy(); resolve({ status: 0, json: { _error: 'timeout' } }); });
- req.write(payload);
- req.end();
- });
- }
- const candidatePaths = [
- // more granular attempts
- '/api/v1/douyin/fetch_video_search_v2',
- '/api/v1/douyin/fetch_user_search_v2',
- '/api/v1/douyin/app/v2/fetch_video_search_v2',
- '/api/v1/douyin/app/v2/fetch_user_search_v2',
- '/api/v1/douyin/app/v1/fetch_video_search_v2',
- '/api/v1/douyin/app/v1/fetch_user_search_v2',
- // 按图中 apifox 路径 id 尝试完整路径
- '/api/v1/douyin_search/v2/api_v1_douyin_search_fetch_video_search_v2_post',
- '/api/v1/douyin_search/v2/api_v1_douyin_search_fetch_user_search_v2_post',
- // 重试已知的 fetch_user_search_result_v2(曾 200),看 POST 是否不同
- '/api/v1/douyin/web/fetch_user_search_result_v2',
- // 官方 API v3 带 _v2 后缀
- '/api/v1/douyin/app/v3/fetch_video_search_result_v2',
- '/api/v1/douyin/app/v3/fetch_user_search_result_v2',
- // Web V3 / V2
- '/api/v3/douyin/search/fetch_video_search_v2',
- '/api/v3/douyin/search/fetch_user_search_v2',
- ];
- (async () => {
- const keyword = '康恩贝';
- console.log(`Testing search for "${keyword}"\n`);
- const results = [];
- for (const p of candidatePaths) {
- const body = p.includes('user')
- ? { keyword, cursor: 0, sort_type: 0, publish_time: 0, search_id: '' }
- : { keyword, cursor: 0, sort_type: '0', publish_time: '0', filter_duration: '0', content_type: '', search_id: '', backtrace: '' };
- const r = await post(p, body);
- const code = r.json?.code;
- const msg = (r.json?.message_zh || r.json?.message || r.json?.detail?.message_zh || r.json?.detail?.message || '').slice(0, 80);
- const data = r.json?.data;
- const dataKeys = data && typeof data === 'object' && !Array.isArray(data) ? Object.keys(data).slice(0, 8).join(',') : (Array.isArray(data) ? `arr[${data.length}]` : typeof data);
- const row = { path: p, status: r.status, code, msg, dataKeys };
- results.push(row);
- console.log(` [${r.status}] ${p}`);
- console.log(` code=${code} msg="${msg}" data=${dataKeys}`);
- await new Promise((res) => setTimeout(res, 600));
- }
- fs.writeFileSync('data/dy-v2-probe.json', JSON.stringify(results, null, 2), 'utf-8');
- })();
|