Skip to content

案例 3:新闻聚合工具

场景描述

从多个新闻源抓取最新资讯,按时间排序

工具配置

插件信息

  • 插件名称:新闻聚合器
  • 插件备注:聚合多个新闻源,获取最新资讯

工具配置

  • 工具名称:aggregate_news
  • 工具介绍:聚合多个新闻源,返回最新资讯列表
  • 工具参数:
    • sources (字符串): 新闻源,多个用逗号分隔
    • count (整数): 获取数量,默认20

完整代码

js
/**
 * 新闻聚合工具
 *
 * 使用方式:
 * 1. 此工具需要抓取多个新闻源,需要动态打开页面
 * 2. 通过参数 sources 指定新闻源,count 指定数量
 * 3. 参数:sources(新闻源,多个用逗号分隔)、count(获取数量,默认20)
 */
class Tool extends OPENUGC_API_V2 {
  constructor(args) {
    super(args);  // 必须调用 super(args) 才能使用 this.args
    this.sources = (args.sources || 'news.sina.com.cn').split(',');
    this.count = Math.min(args.count || 20, 100);
  }

  async run() {
    const allNews = [];

    // 需要抓取多个新闻源,必须使用 OpenUrl
    for (const source of this.sources) {
      try {
        const page = await this.OpenUrl({
          url: `https://${source}`,
          runAt: 'document-end',
          showLog: false
        });

        const news = await page.execute(`
          const items = [];
          const links = document.querySelectorAll('a[href*="news"], a[href*="article"]');

          for (let link of links) {
            const title = link.innerText?.trim();
            const href = link.href;
            const timeElement = link.closest('li, p, div')?.querySelector('time, .time, .date');

            if (title && title.length > 5 && title.length < 100) {
              items.push({
                title,
                url: href.startsWith('http') ? href : 'https://' + window.location.hostname + href,
                source: window.location.hostname,
                time: timeElement ? timeElement.innerText.trim() : ''
              });
            }

            if (items.length >= 10) break;
          }

          return items.slice(0, ${this.count});
        `);

        allNews.push(...news);
        page.close();

        // 避免请求过频
        await this.sleep(500);
      } catch (error) {
        console.error(`抓取 ${source} 失败:`, error.message);
      }
    }

    // 按标题长度和源排序
    const sortedNews = allNews
      .sort((a, b) => b.title.length - a.title.length)
      .slice(0, this.count);

    return {
      success: true,
      total: sortedNews.length,
      sources: this.sources,
      news: sortedNews.map((item, index) => ({
        ...item,
        rank: index + 1
      })),
      extracted_at: new Date().toISOString()
    };
  }
}

📌 使用说明

此工具需要访问多个新闻源,必须使用 OpenUrl() 动态打开页面。适合场景:

  • 需要抓取多个页面的数据
  • 跨域数据聚合
  • 批量页面处理

相关链接

Released under the MIT License.