/ clis / sinablog / search.js
search.js
 1  import { cli, Strategy } from '@jackwener/opencli/registry';
 2  function normalize(value) {
 3      return typeof value === 'string' ? value.replace(/\s+/g, ' ').trim() : '';
 4  }
 5  function stripHtml(value) {
 6      return value.replace(/<[^>]+>/g, '');
 7  }
 8  async function searchSinaBlog(keyword, limit) {
 9      const url = new URL('https://search.sina.com.cn/api/search');
10      url.searchParams.set('q', keyword);
11      url.searchParams.set('tp', 'mix');
12      url.searchParams.set('sort', '0');
13      url.searchParams.set('page', '1');
14      url.searchParams.set('size', String(Math.max(limit, 10)));
15      url.searchParams.set('from', 'search_result');
16      const resp = await fetch(url, {
17          headers: {
18              'User-Agent': 'Mozilla/5.0',
19              Accept: 'application/json',
20          },
21      });
22      if (!resp.ok)
23          throw new Error(`Sina blog search failed: HTTP ${resp.status}`);
24      const data = await resp.json();
25      const list = Array.isArray(data?.data?.list) ? data.data.list : [];
26      return list
27          .filter((item) => normalize(item?.url).includes('blog.sina.com.cn/s/blog_'))
28          .slice(0, limit)
29          .map((item, index) => ({
30          rank: index + 1,
31          title: normalize(stripHtml(item?.title || '')),
32          author: normalize(item?.media_show || item?.author),
33          date: normalize(item?.time || item?.dataTime),
34          description: normalize(item?.intro || item?.searchSummary).slice(0, 150),
35          url: normalize(item?.url),
36      }));
37  }
38  cli({
39      site: 'sinablog',
40      name: 'search',
41      description: '搜索新浪博客文章(通过新浪搜索)',
42      domain: 'blog.sina.com.cn',
43      strategy: Strategy.PUBLIC,
44      browser: false,
45      args: [
46          { name: 'keyword', required: true, positional: true, help: '搜索关键词' },
47          { name: 'limit', type: 'int', default: 20, help: '返回的文章数量' },
48      ],
49      columns: ['rank', 'title', 'author', 'date', 'description', 'url'],
50      func: async (_page, args) => searchSinaBlog(args.keyword, Math.max(1, Math.min(Number(args.limit) || 20, 50))),
51  });