yuanflow-cli 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/cli.js CHANGED
@@ -17,6 +17,12 @@ import {
17
17
  } from './agent-protocol.js';
18
18
  import { findShortcut, listShortcuts } from './shortcuts.js';
19
19
  import { collectComments } from './comment-collector.js';
20
+ import {
21
+ getWorkDetail,
22
+ getWorkDownload,
23
+ searchContent,
24
+ searchUsers,
25
+ } from './work-tools.js';
20
26
 
21
27
  export async function main(argv) {
22
28
  const args = argv.slice(2);
@@ -52,6 +58,16 @@ export async function main(argv) {
52
58
  return;
53
59
  }
54
60
 
61
+ if (command === 'works') {
62
+ await handleWorks(rest);
63
+ return;
64
+ }
65
+
66
+ if (command === 'search') {
67
+ await handleSearch(rest);
68
+ return;
69
+ }
70
+
55
71
  if (command === 'schema') {
56
72
  await handleSchema(rest);
57
73
  return;
@@ -243,6 +259,72 @@ async function handleComments(args) {
243
259
  });
244
260
  }
245
261
 
262
+ async function handleWorks(args) {
263
+ const { positionals, options } = parseOptions(args);
264
+ const [action = 'detail'] = positionals;
265
+ const platform = options.named?.platform;
266
+ const target = options.named?.target || positionals[1];
267
+ if (!platform) {
268
+ throw new Error('缺少 --platform,例如 douyin、youtube、bilibili。');
269
+ }
270
+ if (!target) {
271
+ throw new Error('缺少 --target 或目标位置参数。');
272
+ }
273
+
274
+ let result;
275
+ if (action === 'detail') {
276
+ result = await getWorkDetail({
277
+ platform,
278
+ target,
279
+ prefer: options.named?.prefer || 'primary',
280
+ kind: options.named?.kind,
281
+ targetKind: options.named?.['target-kind'],
282
+ options,
283
+ });
284
+ } else if (action === 'download') {
285
+ result = await getWorkDownload({
286
+ platform,
287
+ target,
288
+ prefer: options.named?.prefer || 'primary',
289
+ kind: options.named?.kind,
290
+ targetKind: options.named?.['target-kind'],
291
+ options,
292
+ });
293
+ } else {
294
+ throw new Error('未知 works 命令。用法:yuanflow-cli works detail|download --platform douyin --target <作品链接或ID>');
295
+ }
296
+ await outputResult(result, options, {
297
+ command: `works ${action}`,
298
+ meta: { endpoint: result.endpoint.path, kind: result.endpoint.kind || `work-${action}` },
299
+ });
300
+ }
301
+
302
+ async function handleSearch(args) {
303
+ const { positionals, options } = parseOptions(args);
304
+ const [action = 'content'] = positionals;
305
+ const platform = options.named?.platform;
306
+ const keyword = options.named?.keyword || positionals[1];
307
+ if (!platform) {
308
+ throw new Error('缺少 --platform,例如 douyin、xiaohongshu、instagram。');
309
+ }
310
+ if (!keyword) {
311
+ throw new Error('缺少 --keyword 或关键词位置参数。');
312
+ }
313
+
314
+ let result;
315
+ if (action === 'content') {
316
+ result = await searchContent({ platform, keyword, options });
317
+ } else if (action === 'users' || action === 'user') {
318
+ result = await searchUsers({ platform, keyword, options });
319
+ } else {
320
+ throw new Error('未知 search 命令。用法:yuanflow-cli search content|users --platform douyin --keyword <关键词>');
321
+ }
322
+ await outputResult(result, options, {
323
+ command: `search ${action}`,
324
+ meta: { endpoint: result.endpoint.path, kind: result.endpoint.kind || `${action}-search` },
325
+ });
326
+ }
327
+
246
328
  async function handleGeneratedCommand(platform, args) {
247
329
  if (!getPlatforms().includes(platform)) {
248
330
  throw new Error(`未知平台:${platform}。可用平台:${getPlatforms().join(', ')}`);
@@ -397,6 +479,10 @@ function printHelp() {
397
479
  yuanflow-cli commands list
398
480
  yuanflow-cli schema douyin.video-detail
399
481
  yuanflow-cli comments collect --platform douyin --target "https://v.douyin.com/xxx/" --dry-run
482
+ yuanflow-cli works detail --platform douyin --target "https://v.douyin.com/xxx/" --dry-run
483
+ yuanflow-cli works download --platform youtube --target "dQw4w9WgXcQ" --dry-run
484
+ yuanflow-cli search content --platform xiaohongshu --keyword "美妆" --dry-run
485
+ yuanflow-cli search users --platform instagram --keyword "nasa" --dry-run
400
486
  yuanflow-cli list douyin
401
487
 
402
488
  说明:
@@ -0,0 +1,569 @@
1
+ export const DETAIL_ENDPOINTS = {
2
+ douyin: [
3
+ {
4
+ method: 'GET',
5
+ path: '/douyin/web/fetch_one_video_by_share_url',
6
+ targetParam: 'share_url',
7
+ targetMode: 'raw-url',
8
+ description: '抖音作品详情,优先使用分享链接。',
9
+ },
10
+ {
11
+ method: 'GET',
12
+ path: '/douyin/web/fetch_one_video',
13
+ targetParam: 'aweme_id',
14
+ targetMode: 'id',
15
+ description: '抖音作品详情,使用 aweme_id。',
16
+ },
17
+ {
18
+ method: 'GET',
19
+ path: '/douyin/app/v3/fetch_one_video_by_share_url',
20
+ targetParam: 'share_url',
21
+ targetMode: 'raw-url',
22
+ prefer: 'fallback',
23
+ description: '抖音作品详情备用 app v3 接口。',
24
+ },
25
+ ],
26
+ xiaohongshu: [
27
+ {
28
+ method: 'GET',
29
+ path: '/xiaohongshu/web_v3/fetch_note_detail',
30
+ targetParam: 'note_id',
31
+ targetMode: 'id',
32
+ optionParams: { 'xsec-token': 'xsec_token' },
33
+ description: '小红书笔记详情。',
34
+ },
35
+ ],
36
+ bilibili: [
37
+ {
38
+ method: 'GET',
39
+ path: '/bilibili/web/fetch_one_video_v3',
40
+ targetParam: 'url',
41
+ targetMode: 'raw-url',
42
+ description: 'B站视频详情,优先使用视频 URL。',
43
+ },
44
+ {
45
+ method: 'GET',
46
+ path: '/bilibili/web/fetch_one_video',
47
+ targetParam: 'bv_id',
48
+ targetMode: 'id',
49
+ description: 'B站视频详情,使用 BV 号。',
50
+ },
51
+ ],
52
+ wechat_channels: [
53
+ {
54
+ method: 'GET',
55
+ path: '/wechat_channels/fetch_video_detail',
56
+ targetParam: 'id',
57
+ targetMode: 'id',
58
+ optionParams: { 'export-id': 'exportId' },
59
+ description: '微信视频号视频详情。',
60
+ },
61
+ ],
62
+ wechat_mp: [
63
+ {
64
+ method: 'GET',
65
+ path: '/wechat_mp/web/fetch_mp_article_detail_json',
66
+ targetParam: 'url',
67
+ targetMode: 'raw',
68
+ description: '微信公众号文章详情 JSON。',
69
+ },
70
+ ],
71
+ tiktok: [
72
+ {
73
+ method: 'GET',
74
+ path: '/tiktok/app/v3/fetch_one_video_by_share_url',
75
+ targetParam: 'share_url',
76
+ targetMode: 'raw-url',
77
+ description: 'TikTok 作品详情,优先使用分享链接。',
78
+ },
79
+ {
80
+ method: 'GET',
81
+ path: '/tiktok/web/fetch_post_detail',
82
+ targetParam: 'itemId',
83
+ targetMode: 'id',
84
+ description: 'TikTok 作品详情,使用 itemId。',
85
+ },
86
+ ],
87
+ instagram: [
88
+ {
89
+ method: 'GET',
90
+ path: '/instagram/v1/fetch_post_by_url',
91
+ targetParam: 'post_url',
92
+ targetMode: 'raw-url',
93
+ description: 'Instagram 帖子详情,使用帖子 URL。',
94
+ },
95
+ {
96
+ method: 'GET',
97
+ path: '/instagram/v3/get_post_info_by_code',
98
+ targetParam: 'code',
99
+ targetMode: 'id',
100
+ targetKind: 'code',
101
+ description: 'Instagram 帖子详情,使用 shortcode。',
102
+ },
103
+ {
104
+ method: 'GET',
105
+ path: '/instagram/v3/get_post_info',
106
+ targetParam: 'media_id',
107
+ targetMode: 'id',
108
+ description: 'Instagram 帖子详情,使用 media_id。',
109
+ },
110
+ ],
111
+ kuaishou: [
112
+ {
113
+ method: 'GET',
114
+ path: '/kuaishou/web/fetch_one_video_by_url',
115
+ targetParam: 'url',
116
+ targetMode: 'raw-url',
117
+ description: '快手作品详情,使用作品链接。',
118
+ },
119
+ {
120
+ method: 'GET',
121
+ path: '/kuaishou/web/fetch_one_video_v2',
122
+ targetParam: 'photo_id',
123
+ targetMode: 'id',
124
+ description: '快手作品详情,使用 photo_id。',
125
+ },
126
+ ],
127
+ reddit: [
128
+ {
129
+ method: 'GET',
130
+ path: '/reddit/app/fetch_post_details',
131
+ targetParam: 'post_id',
132
+ targetMode: 'id',
133
+ optionParams: { 'comment-id': 'comment_id' },
134
+ defaults: { need_format: 'true' },
135
+ description: 'Reddit 帖子详情。',
136
+ },
137
+ ],
138
+ twitter: [
139
+ {
140
+ method: 'GET',
141
+ path: '/twitter/web/fetch_tweet_detail',
142
+ targetParam: 'tweet_id',
143
+ targetMode: 'id',
144
+ description: 'Twitter/X 推文详情。',
145
+ },
146
+ ],
147
+ weibo: [
148
+ {
149
+ method: 'GET',
150
+ path: '/weibo/web_v2/fetch_post_detail',
151
+ targetParam: 'id',
152
+ targetMode: 'id',
153
+ optionParams: { 'long-text': 'is_get_long_text' },
154
+ description: '微博作品详情。',
155
+ },
156
+ {
157
+ method: 'GET',
158
+ path: '/weibo/web/fetch_post_detail',
159
+ targetParam: 'post_id',
160
+ targetMode: 'id',
161
+ prefer: 'fallback',
162
+ description: '微博作品详情备用接口。',
163
+ },
164
+ ],
165
+ youtube: [
166
+ {
167
+ method: 'GET',
168
+ path: '/youtube/web_v2/get_video_info',
169
+ targetParam: 'video_id',
170
+ targetMode: 'id',
171
+ kind: 'video',
172
+ optionParams: { 'language-code': 'language_code', 'need-format': 'need_format' },
173
+ description: 'YouTube 视频详情。',
174
+ },
175
+ {
176
+ method: 'GET',
177
+ path: '/youtube/web_v2/get_post_detail',
178
+ targetParam: 'post_id',
179
+ targetMode: 'id',
180
+ kind: 'post',
181
+ optionParams: {
182
+ 'language-code': 'language_code',
183
+ 'country-code': 'country_code',
184
+ 'need-format': 'need_format',
185
+ },
186
+ description: 'YouTube 社区帖子详情。',
187
+ },
188
+ ],
189
+ zhihu: [
190
+ {
191
+ method: 'GET',
192
+ path: '/zhihu/web/fetch_column_article_detail',
193
+ targetParam: 'article_id',
194
+ targetMode: 'id',
195
+ kind: 'article',
196
+ description: '知乎专栏文章详情。',
197
+ },
198
+ {
199
+ method: 'GET',
200
+ path: '/zhihu/web/fetch_question_answers',
201
+ targetParam: 'question_id',
202
+ targetMode: 'id',
203
+ kind: 'question',
204
+ optionParams: { cursor: 'cursor', limit: 'limit', offset: 'offset', order: 'order' },
205
+ description: '知乎问题回答列表,可作为问题详情和回答入口。',
206
+ },
207
+ ],
208
+ xigua: [
209
+ {
210
+ method: 'GET',
211
+ path: '/xigua/app/v2/fetch_one_video',
212
+ targetParam: 'item_id',
213
+ targetMode: 'id',
214
+ description: '西瓜视频作品详情。',
215
+ },
216
+ ],
217
+ };
218
+
219
+ export const DOWNLOAD_ENDPOINTS = {
220
+ douyin: [
221
+ {
222
+ method: 'GET',
223
+ path: '/douyin/app/v3/fetch_video_high_quality_play_url',
224
+ targetParam: 'share_url',
225
+ targetMode: 'raw-url',
226
+ optionParams: { region: 'region' },
227
+ description: '抖音视频最高画质播放/下载地址查询,优先使用分享链接。',
228
+ },
229
+ {
230
+ method: 'GET',
231
+ path: '/douyin/app/v3/fetch_video_high_quality_play_url',
232
+ targetParam: 'aweme_id',
233
+ targetMode: 'id',
234
+ optionParams: { region: 'region' },
235
+ description: '抖音视频最高画质播放/下载地址查询,使用 aweme_id。',
236
+ },
237
+ {
238
+ method: 'GET',
239
+ path: '/douyin/web/fetch_video_high_quality_play_url',
240
+ targetParam: 'share_url',
241
+ targetMode: 'raw-url',
242
+ optionParams: { region: 'region' },
243
+ prefer: 'fallback',
244
+ description: '抖音视频播放/下载地址备用 web 接口。',
245
+ },
246
+ ],
247
+ bilibili: [
248
+ {
249
+ method: 'GET',
250
+ path: '/bilibili/web/fetch_video_play_info',
251
+ targetParam: 'url',
252
+ targetMode: 'raw-url',
253
+ description: 'B站视频播放信息,使用视频 URL。',
254
+ },
255
+ {
256
+ method: 'GET',
257
+ path: '/bilibili/web/fetch_video_playurl',
258
+ targetParam: 'bv_id',
259
+ targetMode: 'id',
260
+ requiredOptions: ['cid'],
261
+ optionParams: { cid: 'cid' },
262
+ description: 'B站视频流地址,使用 BV 号和 cid。',
263
+ },
264
+ ],
265
+ youtube: [
266
+ {
267
+ method: 'GET',
268
+ path: '/youtube/web_v2/get_video_streams',
269
+ targetParam: 'video_id',
270
+ targetMode: 'id',
271
+ description: 'YouTube 视频流信息。',
272
+ },
273
+ {
274
+ method: 'GET',
275
+ path: '/youtube/web_v2/get_video_streams',
276
+ targetParam: 'video_url',
277
+ targetMode: 'raw-url',
278
+ description: 'YouTube 视频流信息,使用视频 URL。',
279
+ },
280
+ {
281
+ method: 'GET',
282
+ path: '/youtube/web_v2/get_signed_stream_url',
283
+ targetParam: 'video_id',
284
+ targetMode: 'id',
285
+ requiredOptions: ['itag'],
286
+ optionParams: { itag: 'itag' },
287
+ prefer: 'signed',
288
+ description: 'YouTube 已签名视频流 URL,需要 itag。',
289
+ },
290
+ ],
291
+ xigua: [
292
+ {
293
+ method: 'GET',
294
+ path: '/xigua/app/v2/fetch_one_video_play_url',
295
+ targetParam: 'item_id',
296
+ targetMode: 'id',
297
+ description: '西瓜视频播放链接。',
298
+ },
299
+ ],
300
+ };
301
+
302
+ export const CONTENT_SEARCH_ENDPOINTS = {
303
+ bilibili: {
304
+ method: 'GET',
305
+ path: '/bilibili/web/fetch_general_search',
306
+ keywordParam: 'keyword',
307
+ defaults: { order: 'totalrank', page: '1', page_size: '20' },
308
+ optionParams: {
309
+ order: 'order',
310
+ page: 'page',
311
+ 'page-size': 'page_size',
312
+ duration: 'duration',
313
+ 'pubtime-begin': 'pubtime_begin_s',
314
+ 'pubtime-end': 'pubtime_end_s',
315
+ },
316
+ description: 'B站综合搜索。',
317
+ },
318
+ douyin: {
319
+ method: 'POST',
320
+ path: '/douyin/search/fetch_general_search_v2',
321
+ keywordParam: 'keyword',
322
+ bodyMode: true,
323
+ defaults: {
324
+ cursor: 0,
325
+ sort_type: '0',
326
+ publish_time: '0',
327
+ filter_duration: '0',
328
+ content_type: '0',
329
+ search_id: '',
330
+ backtrace: '',
331
+ },
332
+ optionParams: {
333
+ cursor: 'cursor',
334
+ sort: 'sort_type',
335
+ 'sort-type': 'sort_type',
336
+ 'publish-time': 'publish_time',
337
+ duration: 'filter_duration',
338
+ 'filter-duration': 'filter_duration',
339
+ 'content-type': 'content_type',
340
+ type: 'content_type',
341
+ 'search-id': 'search_id',
342
+ backtrace: 'backtrace',
343
+ },
344
+ description: '抖音综合搜索 V2。',
345
+ },
346
+ xiaohongshu: {
347
+ method: 'GET',
348
+ path: '/xiaohongshu/web_v3/fetch_search_notes',
349
+ keywordParam: 'keyword',
350
+ optionParams: { page: 'page', sort: 'sort', type: 'note_type', 'note-type': 'note_type' },
351
+ description: '小红书笔记搜索。',
352
+ },
353
+ wechat_channels: {
354
+ method: 'GET',
355
+ path: '/wechat_channels/fetch_search_ordinary',
356
+ keywordParam: 'keywords',
357
+ description: '微信视频号综合搜索。',
358
+ },
359
+ tiktok: {
360
+ method: 'GET',
361
+ path: '/tiktok/app/v3/fetch_general_search_result',
362
+ keywordParam: 'keyword',
363
+ optionParams: {
364
+ cursor: 'offset',
365
+ offset: 'offset',
366
+ count: 'count',
367
+ sort: 'sort_type',
368
+ 'sort-type': 'sort_type',
369
+ 'publish-time': 'publish_time',
370
+ },
371
+ description: 'TikTok 综合搜索。',
372
+ },
373
+ instagram: {
374
+ method: 'GET',
375
+ path: '/instagram/v3/general_search',
376
+ keywordParam: 'query',
377
+ optionParams: {
378
+ cursor: 'next_max_id',
379
+ 'next-max-id': 'next_max_id',
380
+ 'rank-token': 'rank_token',
381
+ metadata: 'enable_metadata',
382
+ },
383
+ description: 'Instagram 综合搜索。',
384
+ },
385
+ kuaishou: {
386
+ method: 'GET',
387
+ path: '/kuaishou/app/search_comprehensive',
388
+ keywordParam: 'keyword',
389
+ optionParams: {
390
+ cursor: 'pcursor',
391
+ pcursor: 'pcursor',
392
+ sort: 'sort_type',
393
+ 'sort-type': 'sort_type',
394
+ 'publish-time': 'publish_time',
395
+ duration: 'duration',
396
+ scope: 'search_scope',
397
+ },
398
+ description: '快手综合搜索。',
399
+ },
400
+ reddit: {
401
+ method: 'GET',
402
+ path: '/reddit/app/fetch_dynamic_search',
403
+ keywordParam: 'query',
404
+ defaults: { search_type: 'post' },
405
+ optionParams: {
406
+ type: 'search_type',
407
+ 'search-type': 'search_type',
408
+ sort: 'sort',
409
+ cursor: 'after',
410
+ after: 'after',
411
+ 'time-range': 'time_range',
412
+ 'safe-search': 'safe_search',
413
+ 'allow-nsfw': 'allow_nsfw',
414
+ 'need-format': 'need_format',
415
+ },
416
+ description: 'Reddit 动态搜索,默认搜索帖子。',
417
+ },
418
+ twitter: {
419
+ method: 'GET',
420
+ path: '/twitter/web/fetch_search_timeline',
421
+ keywordParam: 'keyword',
422
+ optionParams: { type: 'search_type', 'search-type': 'search_type', cursor: 'cursor' },
423
+ description: 'Twitter/X 搜索时间线。',
424
+ },
425
+ weibo: {
426
+ method: 'GET',
427
+ path: '/weibo/web_v2/fetch_advanced_search',
428
+ keywordParam: 'q',
429
+ optionParams: {
430
+ page: 'page',
431
+ type: 'search_type',
432
+ 'search-type': 'search_type',
433
+ 'include-type': 'include_type',
434
+ timescope: 'timescope',
435
+ },
436
+ description: '微博高级搜索。',
437
+ },
438
+ youtube: {
439
+ method: 'GET',
440
+ path: '/youtube/web_v2/get_general_search_v2',
441
+ keywordParam: 'keyword',
442
+ optionParams: {
443
+ cursor: 'continuation_token',
444
+ 'continuation-token': 'continuation_token',
445
+ 'upload-date': 'upload_date',
446
+ type: 'type',
447
+ duration: 'duration',
448
+ features: 'features',
449
+ sort: 'sort_by',
450
+ 'sort-by': 'sort_by',
451
+ },
452
+ description: 'YouTube 综合搜索。',
453
+ },
454
+ zhihu: {
455
+ method: 'GET',
456
+ path: '/zhihu/web/fetch_article_search_v3',
457
+ keywordParam: 'keyword',
458
+ optionParams: {
459
+ cursor: 'offset',
460
+ offset: 'offset',
461
+ count: 'limit',
462
+ limit: 'limit',
463
+ sort: 'sort',
464
+ vertical: 'vertical',
465
+ 'time-interval': 'time_interval',
466
+ },
467
+ description: '知乎文章搜索。',
468
+ },
469
+ xigua: {
470
+ method: 'GET',
471
+ path: '/xigua/app/v2/search_video',
472
+ keywordParam: 'keyword',
473
+ optionParams: {
474
+ cursor: 'offset',
475
+ offset: 'offset',
476
+ sort: 'order_type',
477
+ 'order-type': 'order_type',
478
+ 'min-duration': 'min_duration',
479
+ 'max-duration': 'max_duration',
480
+ },
481
+ description: '西瓜视频搜索。',
482
+ },
483
+ };
484
+
485
+ export const USER_SEARCH_ENDPOINTS = {
486
+ douyin: {
487
+ method: 'POST',
488
+ path: '/douyin/search/fetch_user_search_v2',
489
+ keywordParam: 'keyword',
490
+ bodyMode: true,
491
+ defaults: { cursor: 0 },
492
+ optionParams: { cursor: 'cursor' },
493
+ description: '抖音用户搜索 V2。',
494
+ },
495
+ xiaohongshu: {
496
+ method: 'GET',
497
+ path: '/xiaohongshu/web_v3/fetch_search_users',
498
+ keywordParam: 'keyword',
499
+ optionParams: { page: 'page' },
500
+ description: '小红书用户搜索。',
501
+ },
502
+ wechat_channels: {
503
+ method: 'GET',
504
+ path: '/wechat_channels/fetch_user_search',
505
+ keywordParam: 'keywords',
506
+ optionParams: { page: 'page' },
507
+ description: '微信视频号用户搜索。',
508
+ },
509
+ tiktok: {
510
+ method: 'GET',
511
+ path: '/tiktok/app/v3/fetch_user_search_result',
512
+ keywordParam: 'keyword',
513
+ optionParams: {
514
+ cursor: 'offset',
515
+ offset: 'offset',
516
+ count: 'count',
517
+ 'follower-count': 'user_search_follower_count',
518
+ 'profile-type': 'user_search_profile_type',
519
+ 'other-pref': 'user_search_other_pref',
520
+ },
521
+ description: 'TikTok 用户搜索。',
522
+ },
523
+ instagram: {
524
+ method: 'GET',
525
+ path: '/instagram/v3/search_users',
526
+ keywordParam: 'query',
527
+ optionParams: { 'rank-token': 'rank_token' },
528
+ description: 'Instagram 用户搜索。',
529
+ },
530
+ kuaishou: {
531
+ method: 'GET',
532
+ path: '/kuaishou/app/search_user_v2',
533
+ keywordParam: 'keyword',
534
+ optionParams: { page: 'page' },
535
+ description: '快手用户搜索。',
536
+ },
537
+ weibo: {
538
+ method: 'GET',
539
+ path: '/weibo/web_v2/fetch_user_search',
540
+ keywordParam: 'query',
541
+ optionParams: {
542
+ page: 'page',
543
+ region: 'region',
544
+ auth: 'auth',
545
+ gender: 'gender',
546
+ age: 'age',
547
+ nickname: 'nickname',
548
+ tag: 'tag',
549
+ school: 'school',
550
+ work: 'work',
551
+ },
552
+ description: '微博用户搜索。',
553
+ },
554
+ youtube: {
555
+ method: 'GET',
556
+ path: '/youtube/web_v2/search_channels',
557
+ keywordParam: 'keyword',
558
+ optionParams: { cursor: 'continuation_token', 'continuation-token': 'continuation_token', 'need-format': 'need_format' },
559
+ description: 'YouTube 频道搜索。',
560
+ },
561
+ zhihu: {
562
+ method: 'GET',
563
+ path: '/zhihu/web/fetch_user_search_v3',
564
+ keywordParam: 'keyword',
565
+ optionParams: { cursor: 'offset', offset: 'offset', count: 'limit', limit: 'limit' },
566
+ description: '知乎用户搜索。',
567
+ },
568
+ };
569
+