Claude Skill

kuaishou-comment

快手评论分析工具。输入作品链接即可获取一级评论数据,支持分页浏览、评论情感分析(积极/负面/需求/竞品),生成精美 HTML 报告。当用户需要查看快手作品评论、分析评论舆情、了解用户反馈时使用。触发词:快手评论、作品评论、评论查询、评论分析、评论舆情、看评论。

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download redfox-data-redfox-community-skills_kuaishou-comment-5e7b435.zip · 22 KB
Part of redfox-data/redfox-community — 66 skills

Install

skills CLI npx skills add https://github.com/redfox-data/redfox-community/tree/main/skills/kuaishou-comment
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install redfox-data-redfox-community@llmmart
Git git clone https://github.com/redfox-data/redfox-community.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole redfox-data/redfox-community collection as a plugin from our marketplace. Git is the plain clone.

README

快手评论分析 / kuaishou-comment


简介

输入快手作品链接即可获取评论数据,支持分页浏览、四维情感分析(积极/负面/需求/竞品)和精美可视化报告生成。

核心价值

  • 即输即看:粘贴作品链接就能拉取评论区数据,每页展示完整评论表格,点赞、回复、IP 属地一览无余。
  • 智能舆情分析:自动将评论归为积极、负面、需求、竞品四类,提取关键词和代表评论,快速了解舆论风向。
  • 分页浏览,越看越全:支持逐页翻页,每次翻页自动累计分析所有已读评论,不遗漏任何信息。
  • 一键导出报告:生成深色主题交互式 HTML 报告,多页自动合并、超 3 页智能折叠,支持离线保存和分享。

适用对象

  • 🔍 快手创作者 — 快速了解作品评论区反馈,发现粉丝需求与选题灵感。
  • 📊 运营 / 数据分析 — 追踪快手作品的用户舆情,掌握内容影响力与受众态度。
  • 🏢 品牌 / MCN — 监控竞品与行业关键词的评论区表现,辅助内容策略决策。

功能特性

核心功能

  • 评论获取:粘贴作品链接即获取评论,支持 cursor 游标逐页翻页,每页展示完整数据。
  • 置顶标记:置顶评论特殊标识,一眼识别重要评论。
  • 四维情感分析:每次查询自动输出积极/负面/需求/竞品四类占比与摘要,翻页时累计分析更全面。
  • 可视化报告:单页生成包含当前页数据的 HTML 报告,多页自动合并为一份、超 3 页智能折叠。

密钥获取与安全说明

  • 本技能需要使用环境变量:REDFOX_API_KEY。
  • REDFOX_API_KEY 由 红狐 hub (https://redfox.hk)提供。
  • 请前往 红狐 hub 注册账号,获取 REDFOX_API_KEY。
  • 配置设备环境变量 REDFOX_API_KEY 后使用本技能。
  • 在提供密钥前,请先确认密钥来源、可用范围、有效期及是否支持重置/撤销。
  • 禁止在代码、提示词、日志或输出文件中硬编码/明文暴露密钥。

使用指南

直接用自然语言发送快手作品链接或 opusId 即可,无需记忆命令。

常用说法速查

意图 示例话术 效果
查看评论 「https://www.kuaishou.com/short-video/3x4ibfzs5e68yxu 这个作品的评论怎么样」 获取评论表格 + 四维情感分析
直接指定 ID 「查看快手作品 3x4ibfzs5e68yxu 的评论」 同上,跳过链接提取
翻页 「下一页」 继续拉取下一页评论,累计分析
导出报告 「生成 html」 已浏览的所有页面合并为一份完整报告

输出示例

查询后你将收到:

📊 评论表格:当前页全部评论,含评论人、评论内容、点赞数、回复数、时间和 IP 属地。

📈 AI 评论总结:四维分析(积极/负面/需求/竞品),含占比、摘要和代表性评论引用。

📄 翻页提示:若还有下一页,提示「回复『下一页』继续查看」。


使用场景

场景 角色 示例问法 收益
查看作品反馈 快手创作者 「我刚发的视频评论区什么情况?」 快速了解观众反应,及时互动
舆情监控 品牌运营 「看看这个产品的快手评论区风向」 掌握竞品或自身舆情,辅助决策
内容选题 内容策划 「最近同赛道爆款视频都聊什么?」 从评论区发掘用户需求与选题灵感
数据分析 数据分析师 「帮我分析这个作品评论的情感分布」 量化评论数据,输出结构化报告

Skill manifest

快手评论分析

📝 简介

输入快手作品链接即可获取一级评论数据,每页 20 条,支持 cursor 游标分页翻页。在对话中展示当前页全部评论及 AI 总结分析,同时生成包含当前页数据和总结的交互式 HTML 报告。

✨ 功能特性

功能模块 能力描述 核心价值
评论获取 粘贴作品链接即可获取评论 实时拉取作品评论区数据
分页浏览 每页 20 条,cursor 游标翻页 逐页浏览大量评论
AI 总结 四维情感分析(积极/负面/需求/竞品) 快速了解评论舆情全貌
置顶标记 置顶评论特殊标识 一眼识别重要评论
HTML 报告 深色主题交互式报告 离线保存/分享分析结果
合并报告 多页合并,超3页自动折叠 一次导出全部评论分析

🔑 鉴权

前往 红狐hub 获取 API Key,通过以下方式配置:

# 方式一:配置文件(如 OpenClaw 的 ~/.openclaw/openclaw.json)
{ "env": { "REDFOX_API_KEY": "ak_xxxx..." } }

# 方式二:终端环境变量
export REDFOX_API_KEY="ak_xxxx..."

🔄 工作流程

Step 1:理解用户意图,提取 opusId

⚠️ 核心规则:用户提供作品链接,Agent 从链接中提取 opusId。

  • 用户提供作品链接(如 https://www.kuaishou.com/short-video/3x4ibfzs5e68yxu),Agent 从链接中提取 opusId
  • 用户也可能直接提供 opusId(如 3x4ibfzs5e68yxu),此时直接使用
  • 若用户未提供作品链接,主动询问:「请提供快手作品链接」
  • 若用户在上一轮对话中查询过某作品的数据,且本轮输入模糊(如"下一页"、"评论分析"),沿用上一轮的 opusId

Step 2:调用评论获取脚本(自动生成 HTML)

⚠️ 每次调用仅请求一页数据(一次 API 请求),不可擅自发起多次调用拉取多页。

脚本每次调用自动生成 HTML 报告(含占位符,未回填分析数据)。终端展示与 HTML 基于同一次 API 调用,确保数据一致。

python3 ~/.agents/skills/kuaishou-comment/scripts/kuaishou_comment_search.py "<opusId>" [--cursor <cursor>] [--page <page>]

参数说明:

参数 说明 默认值
opusId 快手作品 opusId(必填) —
--cursor 游标,首页传空字符串,次页传上一页返回的 nextCursor ""
--page 当前页码(仅用于 HTML 文件名和输出标记) 1
--output-dir HTML 输出目录 ~/Downloads/QoderReports

脚本返回 JSON 字段详见下方评论字段表。

注意: HTML 报告此时仅含评论原始数据,分析占位符待用户确认后回填。

Step 3:对话中展示评论数据 + AI 总结

⚠️ 每次操作仅调用一次 API,获取一页数据。

A1. 告知查询范围

📊 作品「」共获取 N 条评论(第 页),以下是详细数据:

A2. 渲染评论表格(展示当前页全部评论)

格式规则:

  • 评论人列只显示昵称,不展示头像、不生成超链接
  • 评论内容超过 40 字截断加 ...
  • 时间格式化为 MM-DD HH:MM
  • 置顶评论在昵称后加 📌 标记(整行加粗)
  • like_count / reply_count 数字 ≥ 10000 使用 x.xw 格式
  • 每页全部展示,不得截断

A3. AI 评论总结(⚠️ 每次查询(含翻页)必须输出)

首页:基于当前页评论,四维情感分析。

翻页后:基于目前已获取的所有页面累计数据综合分析,标注累计总条数。

分析前需理解快手社区文化(老铁文化、表情符号语义、"奥利给""双击"等特有表达)。

📈 评论总结分析(基于

✅ 积极评价(

  • {要点,引用代表评论关键词}

⚠️ 负面评价(

  • {要点}

💡 用户需求(

  • {要点}

🔍 竞品对比舆情(

  • {仅当提及竞品时输出,否则输出「未提及竞品」}

分析要求:

  • 每条要点引用代表评论关键词/短语
  • 百分比为该类型评论占比,四类总和可能超 100%
  • 必须理解快手社区文化

A4. 翻页提示(⚠️ 紧接在 A3 之后)

  • 若 has_next 为 true:📄 当前第 {page} 页(共 {total_fetched} 条)。回复「下一页」继续查看。
  • 若 has_next 为 false:📄 当前第 {page} 页,已无更多数据。

⚠️ A1~A4 必须在同一轮输出中连续完成,不可省略任何一步。

A4 输出完毕后,询问用户是否需要生成 HTML 可视化报告:

📊 是否需要生成 HTML 可视化报告?

若用户确认,根据已浏览页数选择方式:


仅 1 页 → 单页 HTML(backfill_html.py)

HTML 文件已在 Step 2 生成,直接回填分析数据并打开:

python3 ~/.agents/skills/kuaishou-comment/scripts/backfill_html.py "<html_path>" --analysis-json '<分析JSON>'
open "<html_path>"

2 页及以上 → 合并报告(consolidate_report.py)

收集所有已浏览页面的 JSON 数据,生成一份包含全部评论和累计分析的完整 HTML。按页码分区展示,超过 3 页时自动折叠,提示用户点击展开。

python3 ~/.agents/skills/kuaishou-comment/scripts/consolidate_report.py "<opusId>" \
  --pages-json '[{"page":1,"total":31,"comments":[...]},{"page":2,"total":20,"comments":[...]}]' \
  --analysis-json '<累计分析JSON>'
open "<html_path>"
参数 说明
opusId 快手作品 opusId(位置参数)
--pages-json 多页数据 JSON 数组,每项含 page、total、comments
--analysis-json 累计分析 JSON(字段同 backfill)

pages 数据从各次脚本调用输出中收集;累计分析基于 A3 翻页后综合分析。


分析 JSON 字段说明:

字段 类型 说明
positive_ratio string 积极评价占比(纯数字,如 "62",模板自动追加 %)
negative_ratio string 负面评价占比
demand_ratio string 用户需求占比
competitor_ratio string 竞品对比占比
positive_summary string 积极评价摘要(HTML ul 格式)
negative_summary string 负面评价摘要
demand_summary string 用户需求摘要
competitor_summary string 竞品对比摘要

Step 4:翻页处理(用户回复「下一页」等时)

  1. 沿用 opusId
  2. 使用上一页的 nextCursor
  3. 重新调用脚本:python3 ~/.agents/skills/kuaishou-comment/scripts/kuaishou_comment_search.py "<opusId>" --cursor "<nextCursor>" --page <page>
  4. 完整执行 A1~A4,A3 基于累计综合分析
  5. A4 后询问是否需要 HTML

翻页规则: has_next true → 用 nextCursor 翻页;false → 已无更多。cursor 原样传递,不可修改。

Step 5:错误处理

错误类型 处理方式
无 API Key 提示配置 REDFOX_API_KEY
作品链接无效 提示「未找到该作品的评论,请检查作品链接是否正确」
接口返回错误 显示错误码和错误信息
获取 0 条评论 提示「该作品暂无评论」
网络请求超时 提示「网络请求超时,请稍后重试」

📋 依赖

脚本使用 urllib(Python 标准库),无需额外安装依赖。


🎯 使用示例

示例 1:查看指定作品的评论

用户:查看快手作品 3x4ibfzs5e68yxu 的评论
助手:调用脚本 → 展示当前页 + AI总结 → 询问HTML → backfill → open

示例 2:通过链接查询

用户:https://www.kuaishou.com/short-video/3x4ibfzs5e68yxu 这个作品的评论怎么样
助手:提取 opusId → 调用脚本 → 展示分析 → 询问HTML

示例 3:翻页后合并导出

用户:下一页 → 下一页 → 生成html
助手:收集3页JSON → consolidate_report.py → 1个HTML含全部评论+折叠 → open
Files (redfox-community)
  • assets
    • consolidate_report_template.html 12 KB · in bundle
    • report_template.html 12 KB · in bundle
  • scripts
    • backfill_html.py 2.8 KB
      #!/usr/bin/env python3
      """
      HTML 报告分析数据回填脚本
      将 AI 分析结果回填到脚本生成的 HTML 报告中的 {{PLACEHOLDER}} 占位符。
      用法: python3 backfill_html.py <html_path> --analysis-json '<json>'
            或通过 stdin 传入 JSON: echo '<json>' | python3 backfill_html.py <html_path>
      """
      
      import sys
      import os
      import json
      import argparse
      
      
      def backfill(html_path: str, analysis: dict) -> None:
          """读取 HTML 文件,替换分析占位符,写回文件"""
          if not os.path.exists(html_path):
              print(f"[error] HTML 文件不存在: {html_path}", file=sys.stderr)
              sys.exit(1)
      
          with open(html_path, "r", encoding="utf-8") as f:
              html = f.read()
      
          # 统计栏比例
          ratio_map = {
              "{{POSITIVE_RATIO}}": str(analysis.get("positive_ratio", "--")),
              "{{NEGATIVE_RATIO}}": str(analysis.get("negative_ratio", "--")),
              "{{DEMAND_RATIO}}": str(analysis.get("demand_ratio", "--")),
              "{{COMPETITOR_RATIO}}": str(analysis.get("competitor_ratio", "--")),
          }
      
          for key, val in ratio_map.items():
              html = html.replace(key, val)
      
          # 摘要卡片内容
          summary_map = {
              "{{SUMMARY_POSITIVE}}": analysis.get("positive_summary", ""),
              "{{SUMMARY_NEGATIVE}}": analysis.get("negative_summary", ""),
              "{{SUMMARY_DEMAND}}": analysis.get("demand_summary", ""),
              "{{SUMMARY_COMPETITOR}}": analysis.get("competitor_summary", ""),
          }
      
          for key, val in summary_map.items():
              html = html.replace(key, val)
      
          with open(html_path, "w", encoding="utf-8") as f:
              f.write(html)
      
          print(f"[backfill] 分析数据已回填到: {html_path}", file=sys.stderr)
      
      
      def main():
          parser = argparse.ArgumentParser(description="HTML 报告分析数据回填")
          parser.add_argument("html_path", help="HTML 报告文件路径")
          parser.add_argument(
              "--analysis-json", dest="analysis_json", type=str, default=None,
              help='分析数据 JSON 字符串,格式: {"positive_ratio":45,"positive_summary":"<ul>...</ul>",...}',
          )
      
          args = parser.parse_args()
      
          # 优先从 --analysis-json 参数读取,其次从 stdin 读取
          if args.analysis_json:
              try:
                  analysis = json.loads(args.analysis_json)
              except json.JSONDecodeError as e:
                  print(f"[error] JSON 解析失败: {e}", file=sys.stderr)
                  sys.exit(1)
          else:
              # 从 stdin 读取 JSON
              try:
                  raw = sys.stdin.read()
                  analysis = json.loads(raw) if raw.strip() else {}
              except json.JSONDecodeError as e:
                  print(f"[error] stdin JSON 解析失败: {e}", file=sys.stderr)
                  sys.exit(1)
      
          if not analysis:
              print("[warn] 未提供分析数据,跳过回填", file=sys.stderr)
              return
      
          backfill(args.html_path, analysis)
      
      
      if __name__ == "__main__":
          main()
      
    • consolidate_report.py 9.1 KB
      #!/usr/bin/env python3
      """
      快手评论分析 - 合并报告生成脚本
      将多页评论数据合并生成一份完整的 HTML 报告,
      包含所有评论和累计分析。超过 3 页时自动折叠。
      
      用法: echo '<json_array>' | python3 consolidate_report.py "<opusId>" --analysis-json '<json>'
            或: python3 consolidate_report.py "<opusId>" --pages-json '<json_array>' --analysis-json '<json>'
      """
      
      import sys
      import os
      import json
      import argparse
      import subprocess
      from datetime import datetime
      
      SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
      TEMPLATE_PATH = os.path.join(SCRIPT_DIR, "..", "assets", "consolidate_report_template.html")
      
      
      def escape_html(text: str) -> str:
          return (text or "").replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;")
      
      
      def build_comment_rows(comments: list) -> str:
          """根据评论列表生成 HTML 表格行"""
          rows = []
          for c in comments:
              is_top = c.get("is_top", False)
              row_class = ' class="top-comment"' if is_top else ""
              pin_badge = '<span class="top-badge">📌 置顶</span>' if is_top else ""
      
              avatar = c.get("user_avatar", "") or ""
              name = escape_html(c.get("user_name", ""))
              content = escape_html(c.get("content", ""))
              like = c.get("like_count", 0) or 0
              reply = c.get("reply_count", 0) or 0
              time_str = (c.get("create_time", "") or "")[5:16]
              ip = escape_html(c.get("ip_location", ""))
      
              row = (
                  f'<tr{row_class}>'
                  f'<td>'
                  f'<div class="user-cell">'
                  f'<img src="{avatar}" class="user-avatar" alt="" onerror="this.style.display=\'none\'" referrerpolicy="no-referrer">'
                  f'<span class="user-name">{name}{pin_badge}</span>'
                  f'</div>'
                  f'</td>'
                  f'<td class="content-cell">{content}</td>'
                  f'<td class="num-cell">{like}</td>'
                  f'<td class="num-cell">{reply}</td>'
                  f'<td class="time-cell">{time_str}</td>'
                  f'<td class="ip-cell">{ip}</td>'
                  f'</tr>'
              )
              rows.append(row)
          return "\n".join(rows)
      
      
      def build_page_sections(pages: list, max_visible: int = 3) -> tuple:
          """
          生成页面 HTML 片段和折叠切换按钮。
          pages: [{"page": 1, "total": 31, "comments": [...]}, ...]
          返回 (page_sections_html, collapse_toggle_html)
          """
          visible_count = 0
          visible_sections = []
          collapsed_sections = []
      
          # 过滤空页
          pages = [p for p in pages if p.get("comments") and len(p["comments"]) > 0]
          total_pages = len(pages)
      
          for i, p in enumerate(pages):
              page_num = p.get("page", i + 1)
              total = p.get("total", len(p.get("comments", [])))
              comments = p.get("comments", [])
      
              table_rows = build_comment_rows(comments)
      
              section_html = (
                  f'<div class="page-section">'
                  f'<h3>📄 第 {page_num} 页 '
                  f'<span class="page-badge">{total} 条</span>'
                  f'</h3>'
                  f'<div class="table-wrapper">'
                  f'<table class="comment-table">'
                  f'<thead>'
                  f'<tr>'
                  f'<th style="width: 160px;">评论人</th>'
                  f'<th>评论内容</th>'
                  f'<th style="width: 70px; text-align: right;">👍 点赞</th>'
                  f'<th style="width: 70px; text-align: right;">💬 回复</th>'
                  f'<th style="width: 110px;">时间</th>'
                  f'<th style="width: 80px;">IP属地</th>'
                  f'</tr>'
                  f'</thead>'
                  f'<tbody>'
                  f'{table_rows}'
                  f'</tbody>'
                  f'</table>'
                  f'</div>'
                  f'</div>'
              )
      
              if total_pages <= max_visible or page_num <= max_visible:
                  visible_sections.append(section_html)
              else:
                  collapsed_sections.append(section_html)
      
          sections_html = "\n".join(visible_sections)
      
          # 折叠区域
          if collapsed_sections:
              hidden_count = sum(
                  p.get("total", len(p.get("comments", [])))
                  for p in pages[max_visible:]
              )
              toggle_html = (
                  f'<div class="collapse-container" id="collapseToggle">'
                  f'<p style="color: var(--text-secondary); margin-bottom: 0.6rem; font-size: 0.85rem;">'
                  f'⚠️ 评论页数较多,已折叠第 {max_visible + 1}-{total_pages} 页(共 {hidden_count} 条)</p>'
                  f'<button class="collapse-toggle" onclick="toggleCollapsed()">'
                  f'📂 展开全部评论'
                  f'</button>'
                  f'</div>'
                  f'<div class="collapsed-pages" id="collapsedPages">'
                  + "\n".join(collapsed_sections) +
                  f'</div>'
              )
          else:
              toggle_html = ""
      
          return sections_html, toggle_html
      
      
      def generate_consolidated_report(
          opus_id: str,
          pages: list,
          analysis: dict,
          output_dir: str = None,
      ) -> str:
          template_path = os.path.normpath(TEMPLATE_PATH)
          if not os.path.exists(template_path):
              print(f"[error] 模板文件不存在: {template_path}", file=sys.stderr)
              sys.exit(1)
      
          with open(template_path, "r", encoding="utf-8") as f:
              html = f.read()
      
          # 过滤空页并合并所有评论
          pages = [p for p in pages if p.get("comments") and len(p["comments"]) > 0]
          all_comments = []
          for p in pages:
              all_comments.extend(p.get("comments", []))
      
          total_pages = len(pages)
          total_comments = len(all_comments)
          total_likes = sum(c.get("like_count", 0) or 0 for c in all_comments)
          now = datetime.now()
      
          # 生成页面区域
          page_sections, collapse_toggle = build_page_sections(pages)
      
          replacements = {
              "{{OPUS_ID}}": escape_html(opus_id),
              "{{DATE}}": now.strftime("%Y-%m-%d"),
              "{{TOTAL_COMMENTS}}": str(total_comments),
              "{{TOTAL_LIKES}}": str(total_likes),
              "{{TOTAL_PAGES}}": str(total_pages),
              "{{TIMESTAMP}}": now.strftime("%Y-%m-%d %H:%M:%S"),
              "{{PAGE_SECTIONS}}": page_sections,
              "{{COLLAPSE_TOGGLE}}": collapse_toggle,
              "{{POSITIVE_RATIO}}": str(analysis.get("positive_ratio", "--")),
              "{{NEGATIVE_RATIO}}": str(analysis.get("negative_ratio", "--")),
              "{{DEMAND_RATIO}}": str(analysis.get("demand_ratio", "--")),
              "{{COMPETITOR_RATIO}}": str(analysis.get("competitor_ratio", "--")),
              "{{SUMMARY_POSITIVE}}": analysis.get("positive_summary", ""),
              "{{SUMMARY_NEGATIVE}}": analysis.get("negative_summary", ""),
              "{{SUMMARY_DEMAND}}": analysis.get("demand_summary", ""),
              "{{SUMMARY_COMPETITOR}}": analysis.get("competitor_summary", ""),
          }
      
          for key, val in replacements.items():
              html = html.replace(key, val)
      
          # 添加 JavaScript 折叠逻辑
          collapse_js = """
      <script>
      function toggleCollapsed() {
          var collapsed = document.getElementById('collapsedPages');
          var btn = document.getElementById('collapseToggle').querySelector('.collapse-toggle');
          if (collapsed.classList.contains('visible')) {
              collapsed.classList.remove('visible');
              btn.textContent = '📂 展开全部评论';
          } else {
              collapsed.classList.add('visible');
              btn.textContent = '📁 收起';
          }
      }
      </script>
      """
          html = html.replace("</body>", collapse_js + "\n</body>")
      
          if output_dir:
              out_dir = os.path.expanduser(output_dir)
          else:
              out_dir = os.path.expanduser("~/Downloads/QoderReports")
          os.makedirs(out_dir, exist_ok=True)
      
          filename = f"快手评论分析_{opus_id}_全部{total_pages}页.html"
          file_path = os.path.join(out_dir, filename)
      
          with open(file_path, "w", encoding="utf-8") as f:
              f.write(html)
      
          print(f"[consolidate] 合并报告已生成: {file_path}", file=sys.stderr)
          return file_path
      
      
      def main():
          parser = argparse.ArgumentParser(description="快手评论合并报告生成")
          parser.add_argument("opus_id", help="快手作品 opusId")
          parser.add_argument(
              "--pages-json", dest="pages_json", type=str, default=None,
              help='多页数据 JSON 字符串,格式: [{"page":1,"total":20,"comments":[...]},...]',
          )
          parser.add_argument(
              "--analysis-json", dest="analysis_json", type=str, default=None,
              help='累计分析数据 JSON',
          )
          parser.add_argument(
              "--output-dir", dest="output_dir", type=str, default=None,
              help="HTML 输出目录",
          )
      
          args = parser.parse_args()
      
          # 读取 pages 数据
          if args.pages_json:
              pages = json.loads(args.pages_json)
          else:
              raw = sys.stdin.read()
              pages = json.loads(raw) if raw.strip() else []
      
          if not pages:
              print("[error] 未提供评论数据", file=sys.stderr)
              sys.exit(1)
      
          # 读取分析数据
          if args.analysis_json:
              analysis = json.loads(args.analysis_json)
          else:
              analysis = {}
      
          html_path = generate_consolidated_report(
              opus_id=args.opus_id,
              pages=pages,
              analysis=analysis,
              output_dir=args.output_dir,
          )
      
          print(json.dumps({"html_path": html_path}, ensure_ascii=False))
      
          # 自动在浏览器中打开
          subprocess.run(["open", html_path])
      
      
      if __name__ == "__main__":
          main()
      
    • kuaishou_comment_search.py 8.8 KB
      #!/usr/bin/env python3
      """
      快手评论分析脚本
      调用 Redfox API 获取快手作品一级评论数据,同步生成 HTML 报告
      用法: python3 kuaishou_comment_search.py "<opusId>" [--cursor ""] [--page 1] [--no-html] [--output-dir ~/Downloads/QoderReports]
      """
      
      import sys
      import os
      import json
      import argparse
      import urllib.request
      import urllib.error
      from datetime import datetime
      
      API_URL = "https://redfox.hk/story/api/ks/ability/commentList"
      
      # 脚本所在目录,用于定位模板
      SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
      TEMPLATE_PATH = os.path.join(SCRIPT_DIR, "..", "assets", "report_template.html")
      
      
      def get_api_key() -> str:
          val = os.environ.get("REDFOX_API_KEY", "")
          if not val:
              print("[error] 未找到环境变量 REDFOX_API_KEY,请确认已设置 API Key", file=sys.stderr)
              print("[hint] 获取 API Key: https://redfox.hk/settings/api-keys?source=github", file=sys.stderr)
              print("[hint] 配置: export REDFOX_API_KEY=ak_xxxx...", file=sys.stderr)
              sys.exit(1)
          return val
      
      
      def call_api(opus_id: str, cursor: str, api_key: str) -> dict:
          """单次调用评论接口,返回原始 JSON 数据"""
          payload = json.dumps({
              "opusId": opus_id,
              "cursor": cursor or "",
              "source": "快手评论分析-GitHub",
          }).encode("utf-8")
      
          req = urllib.request.Request(
              API_URL,
              data=payload,
              headers={
                  "Content-Type": "application/json",
                  "X-API-Key": api_key,
                  "User-Agent": "QoderWork/1.0",
              },
              method="POST",
          )
      
          try:
              with urllib.request.urlopen(req, timeout=30) as resp:
                  result = json.loads(resp.read().decode("utf-8"))
          except urllib.error.HTTPError as e:
              body = e.read().decode("utf-8", errors="replace")
              print(f"[error] HTTP {e.code}: {body}", file=sys.stderr)
              sys.exit(1)
          except urllib.error.URLError as e:
              print(f"[error] 网络请求失败: {e.reason}", file=sys.stderr)
              sys.exit(1)
          except (json.JSONDecodeError, KeyError, TypeError) as e:
              print(f"[error] 数据解析异常: {e}", file=sys.stderr)
              sys.exit(1)
      
          code = result.get("code")
          if code != 2000:
              print(f"[error] 接口返回错误: code={code}, msg={result.get('msg', '未知')}", file=sys.stderr)
              sys.exit(1)
      
          return result
      
      
      def format_comment(raw: dict) -> dict:
          """将 API 返回的原始评论格式化为统一结构
      
          API 返回字段(data.comments[]):
          cid, content, likeNum, replyNum, createTime,
          area, nickname, avatar, uid, bottomTags
          """
          user_uid = raw.get("uid", "") or ""
          nickname = (raw.get("nickname", "") or "").strip()
          avatar = raw.get("avatar", "") or ""
      
          # 置顶判断:bottomTags 中包含 "top_comment"
          bottom_tags_str = raw.get("bottomTags", "") or ""
          is_top = "top_comment" in bottom_tags_str
      
          return {
              "comment_id": raw.get("cid", ""),
              "content": (raw.get("content", "") or "").strip(),
              "like_count": raw.get("likeNum", 0) or 0,
              "reply_count": raw.get("replyNum", 0) or 0,
              "create_time": raw.get("createTime", "") or "",
              "ip_location": raw.get("area", "") or "",
              "user_name": nickname,
              "user_avatar": avatar,
              "user_id": user_uid,
              "is_top": is_top,
          }
      
      
      def fetch_comments(opus_id: str, cursor: str, api_key: str) -> tuple:
          """
          单次调用接口获取当前页评论数据(每次仅调用一次 API)。
          返回 (comments_list, has_next, next_cursor)
          """
          result = call_api(opus_id, cursor, api_key)
          data = result.get("data") or {}
          page_comments = data.get("comments") or []
          if not isinstance(page_comments, list):
              page_comments = []
          all_comments = [format_comment(c) for c in page_comments]
      
          # 判断是否有下一页:cursor 有值且不为终止标识 "no_more"
          raw_cursor = data.get("cursor", "") or ""
          has_next = bool(raw_cursor) and raw_cursor != "no_more"
          next_cursor = raw_cursor
      
          return all_comments, has_next, next_cursor
      
      
      def escape_html(text: str) -> str:
          """HTML 实体转义"""
          return (text or "").replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace('"', "&quot;")
      
      
      def build_comment_rows(comments: list) -> str:
          """根据评论列表生成 HTML 表格行"""
          rows = []
          for c in comments:
              is_top = c.get("is_top", False)
              row_class = ' class="top-comment"' if is_top else ""
              pin_badge = '<span class="top-badge">📌 置顶</span>' if is_top else ""
      
              avatar = c.get("user_avatar", "") or ""
              name = escape_html(c.get("user_name", ""))
              content = escape_html(c.get("content", ""))
              like = c.get("like_count", 0) or 0
              reply = c.get("reply_count", 0) or 0
              time_str = (c.get("create_time", "") or "")[5:16]  # YYYY-MM-DD HH:MM:SS → MM-DD HH:MM
              ip = escape_html(c.get("ip_location", ""))
      
              row = (
                  f'<tr{row_class}>'
                  f'<td>'
                  f'<div class="user-cell">'
                  f'<img src="{avatar}" class="user-avatar" alt="" onerror="this.style.display=\'none\'" referrerpolicy="no-referrer">'
                  f'<span class="user-name">{name}{pin_badge}</span>'
                  f'</div>'
                  f'</td>'
                  f'<td class="content-cell">{content}</td>'
                  f'<td class="num-cell">{like}</td>'
                  f'<td class="num-cell">{reply}</td>'
                  f'<td class="time-cell">{time_str}</td>'
                  f'<td class="ip-cell">{ip}</td>'
                  f'</tr>'
              )
              rows.append(row)
          return "\n".join(rows)
      
      
      def generate_html_report(opus_id: str, current_page: int, comments: list, output_dir: str = None) -> str:
          """
          读取 HTML 模板,填充评论数据,生成报告文件。
          返回生成的 HTML 文件绝对路径。
          """
          template_path = os.path.normpath(TEMPLATE_PATH)
          if not os.path.exists(template_path):
              print(f"[warn] 模板文件不存在: {template_path},跳过 HTML 生成", file=sys.stderr)
              return ""
      
          with open(template_path, "r", encoding="utf-8") as f:
              html = f.read()
      
          total = len(comments)
          now = datetime.now()
      
          total_likes = sum(c.get("like_count", 0) or 0 for c in comments)
      
          replacements = {
              "{{OPUS_ID}}": escape_html(opus_id),
              "{{DATE}}": now.strftime("%Y-%m-%d"),
              "{{TOTAL_COMMENTS}}": str(total),
              "{{COMMENT_ROWS}}": build_comment_rows(comments),
              "{{TIMESTAMP}}": now.strftime("%Y-%m-%d %H:%M:%S"),
              "{{TOTAL_LIKES}}": str(total_likes),
              "{{PAGE}}": str(current_page),
          }
      
          for key, val in replacements.items():
              html = html.replace(key, val)
      
          if output_dir:
              out_dir = os.path.expanduser(output_dir)
          else:
              out_dir = os.path.expanduser("~/Downloads/QoderReports")
          os.makedirs(out_dir, exist_ok=True)
      
          filename = f"快手评论分析_{opus_id}_p{current_page}.html"
          file_path = os.path.join(out_dir, filename)
      
          with open(file_path, "w", encoding="utf-8") as f:
              f.write(html)
      
          print(f"[html] HTML 报告已生成: {file_path}", file=sys.stderr)
          return file_path
      
      
      def main():
          parser = argparse.ArgumentParser(description="快手评论分析")
          parser.add_argument("opus_id", help="快手作品 opusId")
          parser.add_argument(
              "--cursor", dest="cursor", type=str, default="",
              help="游标(首页传空字符串,次页传上一页返回的 nextCursor)",
          )
          parser.add_argument(
              "--page", dest="page", type=int, default=1,
              help="当前页码(默认 1)",
          )
          parser.add_argument(
              "--no-html", dest="no_html", action="store_true",
              help="跳过 HTML 报告生成",
          )
          parser.add_argument(
              "--output-dir", dest="output_dir", type=str, default=None,
              help="HTML 输出目录(默认 ~/Downloads/QoderReports)",
          )
      
          args = parser.parse_args()
      
          opus_id = args.opus_id.strip()
          if not opus_id:
              print("[error] opusId 不能为空", file=sys.stderr)
              sys.exit(1)
      
          api_key = get_api_key()
      
          comments, has_next, next_cursor = fetch_comments(opus_id, args.cursor, api_key)
      
          total = len(comments)
          current_page = args.page
      
          output = {
              "opus_id": opus_id,
              "current_page": current_page,
              "cursor": args.cursor,
              "next_cursor": next_cursor,
              "total_fetched": total,
              "has_next": has_next,
              "comments": comments,
              "total_count": total,
          }
      
          if not args.no_html:
              html_path = generate_html_report(
                  opus_id=opus_id,
                  current_page=current_page,
                  comments=comments,
                  output_dir=args.output_dir,
              )
              output["html_path"] = html_path
      
          print(json.dumps(output, ensure_ascii=False, indent=2))
      
      
      if __name__ == "__main__":
          main()
      
  • README.en.md 4.1 KB
    # Kuaishou Comment Analysis / kuaishou-comment
    
    ---
    
    ## Overview
    
    Paste a Kuaishou video link to fetch comment data, with paginated browsing, four-dimensional sentiment analysis (positive/negative/demand/competitor), and polished visual report generation.
    
    **Core Value**
    
    - **Paste & View Instantly**: Drop a video link to pull comment data — likes, replies, IP locations displayed in a clean table.
    - **Smart Sentiment Analysis**: Automatically categorizes comments into positive, negative, demand, and competitor types with key phrases and representative quotes for a quick read on public opinion.
    - **Paginated Browsing, Deeper with Every Page**: Flip through comments page by page, with cumulative analysis across all viewed pages for a complete picture.
    - **One-Click Report Export**: Generate a dark-themed interactive HTML report; multi-page comments auto-merge and collapse beyond 3 pages for easy sharing and offline access.
    
    **Target Users**
    
    - 🔍 **Kuaishou Creators** — Quickly gauge audience feedback on your videos and discover content opportunities.
    - 📊 **Operations / Data Analysts** — Track user sentiment on Kuaishou content and measure influencer impact and audience attitudes.
    - 🏢 **Brands / MCNs** — Monitor competitor comment sections and industry keyword performance to inform content strategy.
    
    ---
    
    ## Features
    
    ### Core Capabilities
    
    - **Comment Fetching**: Paste a video link to retrieve comments with cursor-based pagination.
    - **Pinned Comment Highlighting**: Top comments are visually distinguished for quick identification.
    - **Four-Dimensional Analysis**: Each query outputs ratios and summaries across positive, negative, demand, and competitor categories, with cumulative analysis on page turns.
    - **Visual Reports**: Single-page HTML reports for current data, auto-merged multi-page reports with smart collapse beyond 3 pages.
    
    ---
    
    ## API Key Acquisition & Security
    
    - This skill requires the environment variable `REDFOX_API_KEY`.
    - `REDFOX_API_KEY` is provided by [RedFoxHub](https://redfox.hk/settings/api-keys?source=github) (`https://redfox.hk`).
    - Please visit [RedFoxHub](https://redfox.hk?source=github) to register and obtain your `REDFOX_API_KEY`.
    - Configure the `REDFOX_API_KEY` as a device environment variable before using this skill.
    - Before providing the key, verify its source, scope, validity period, and whether it supports reset/revocation.
    - Never hardcode or expose the key in code, prompts, logs, or output files.
    
    ---
    
    ## Usage Guide
    
    Send a Kuaishou video link or opusId in natural language — no commands to memorize.
    
    ### Quick Reference
    
    | Intent | Example | Result |
    | ------ | ------- | ------ |
    | View comments | "https://www.kuaishou.com/short-video/3x4ibfzs5e68yxu — what are people saying?" | Comment table + four-dimensional sentiment analysis |
    | Use video ID directly | "Check comments on video 3x4ibfzs5e68yxu" | Same as above, skip link extraction |
    | Next page | "Next page" | Fetch the next page of comments with cumulative analysis |
    | Export report | "Generate HTML" | Merges all browsed pages into a single complete report |
    
    ### Output Example
    
    After querying you'll receive:
    
    📊 **Comment Table**: All comments on the current page, including username, content, likes, replies, timestamp, and IP location.
    
    📈 **AI Sentiment Summary**: Four-dimensional analysis with ratios, summaries, and representative comment quotes.
    
    📄 **Pagination Hint**: If more pages are available, prompts you to reply "Next page" to continue.
    
    ---
    
    ## Use Cases
    
    | Scenario | Role | Example Query | Benefit |
    | -------- | ---- | ------------- | ------- |
    | Viewer feedback | Creator | "What are people saying under my latest video?" | Quickly gauge audience reactions and engage |
    | Sentiment monitoring | Brand operator | "Show me the comment sentiment on this product" | Track public opinion for data-driven decisions |
    | Content ideation | Content strategist | "What are viewers discussing in trending videos?" | Mine comment sections for audience needs and topic inspiration |
    | Data analysis | Data analyst | "Analyze the emotional distribution of comments on this video" | Quantify comment data into a structured report |
    
  • README.md 3.8 KB
    # 快手评论分析 / kuaishou-comment
    
    ---
    
    ## 简介
    
    输入快手作品链接即可获取评论数据,支持分页浏览、四维情感分析(积极/负面/需求/竞品)和精美可视化报告生成。
    
    **核心价值**
    
    - **即输即看**:粘贴作品链接就能拉取评论区数据,每页展示完整评论表格,点赞、回复、IP 属地一览无余。
    - **智能舆情分析**:自动将评论归为积极、负面、需求、竞品四类,提取关键词和代表评论,快速了解舆论风向。
    - **分页浏览,越看越全**:支持逐页翻页,每次翻页自动累计分析所有已读评论,不遗漏任何信息。
    - **一键导出报告**:生成深色主题交互式 HTML 报告,多页自动合并、超 3 页智能折叠,支持离线保存和分享。
    
    **适用对象**
    
    - 🔍 **快手创作者** — 快速了解作品评论区反馈,发现粉丝需求与选题灵感。
    - 📊 **运营 / 数据分析** — 追踪快手作品的用户舆情,掌握内容影响力与受众态度。
    - 🏢 **品牌 / MCN** — 监控竞品与行业关键词的评论区表现,辅助内容策略决策。
    
    ---
    
    ## 功能特性
    
    ### 核心功能
    
    - **评论获取**:粘贴作品链接即获取评论,支持 cursor 游标逐页翻页,每页展示完整数据。
    - **置顶标记**:置顶评论特殊标识,一眼识别重要评论。
    - **四维情感分析**:每次查询自动输出积极/负面/需求/竞品四类占比与摘要,翻页时累计分析更全面。
    - **可视化报告**:单页生成包含当前页数据的 HTML 报告,多页自动合并为一份、超 3 页智能折叠。
    
    ---
    
    ## 密钥获取与安全说明
    
    - 本技能需要使用环境变量:`REDFOX_API_KEY`。
    - `REDFOX_API_KEY` 由 [红狐 hub](https://redfox.hk/settings/api-keys?source=github) (`https://redfox.hk`)提供。
    - 请前往 [红狐 hub](https://redfox.hk?source=github) 注册账号,获取 `REDFOX_API_KEY`。
    - 配置设备环境变量 `REDFOX_API_KEY` 后使用本技能。
    - 在提供密钥前,请先确认密钥来源、可用范围、有效期及是否支持重置/撤销。
    - 禁止在代码、提示词、日志或输出文件中硬编码/明文暴露密钥。
    
    ---
    
    ## 使用指南
    
    直接用自然语言发送快手作品链接或 opusId 即可,无需记忆命令。
    
    ### 常用说法速查
    
    | 意图 | 示例话术 | 效果 |
    | ---- | -------- | ---- |
    | 查看评论 | 「https://www.kuaishou.com/short-video/3x4ibfzs5e68yxu 这个作品的评论怎么样」 | 获取评论表格 + 四维情感分析 |
    | 直接指定 ID | 「查看快手作品 3x4ibfzs5e68yxu 的评论」 | 同上,跳过链接提取 |
    | 翻页 | 「下一页」 | 继续拉取下一页评论,累计分析 |
    | 导出报告 | 「生成 html」 | 已浏览的所有页面合并为一份完整报告 |
    
    ### 输出示例
    
    查询后你将收到:
    
    📊 **评论表格**:当前页全部评论,含评论人、评论内容、点赞数、回复数、时间和 IP 属地。
    
    📈 **AI 评论总结**:四维分析(积极/负面/需求/竞品),含占比、摘要和代表性评论引用。
    
    📄 **翻页提示**:若还有下一页,提示「回复『下一页』继续查看」。
    
    ---
    
    ## 使用场景
    
    | 场景 | 角色 | 示例问法 | 收益 |
    | ---- | ---- | -------- | ---- |
    | 查看作品反馈 | 快手创作者 | 「我刚发的视频评论区什么情况?」 | 快速了解观众反应,及时互动 |
    | 舆情监控 | 品牌运营 | 「看看这个产品的快手评论区风向」 | 掌握竞品或自身舆情,辅助决策 |
    | 内容选题 | 内容策划 | 「最近同赛道爆款视频都聊什么?」 | 从评论区发掘用户需求与选题灵感 |
    | 数据分析 | 数据分析师 | 「帮我分析这个作品评论的情感分布」 | 量化评论数据,输出结构化报告 |
    
  • SKILL.md 8.5 KB
    ---
    name: kuaishou-comment
    description: 快手评论分析工具。输入作品链接即可获取一级评论数据,支持分页浏览、评论情感分析(积极/负面/需求/竞品),生成精美 HTML 报告。当用户需要查看快手作品评论、分析评论舆情、了解用户反馈时使用。触发词:快手评论、作品评论、评论查询、评论分析、评论舆情、看评论。
    ---
    
    # 快手评论分析
    
    ## 📝 简介
    
    输入快手作品链接即可获取一级评论数据,每页 20 条,支持 cursor 游标分页翻页。在对话中展示当前页全部评论及 AI 总结分析,同时生成包含当前页数据和总结的交互式 HTML 报告。
    
    ## ✨ 功能特性
    
    | 功能模块 | 能力描述 | 核心价值 |
    |---------|---------|---------|
    | 评论获取 | 粘贴作品链接即可获取评论 | 实时拉取作品评论区数据 |
    | 分页浏览 | 每页 20 条,cursor 游标翻页 | 逐页浏览大量评论 |
    | AI 总结 | 四维情感分析(积极/负面/需求/竞品) | 快速了解评论舆情全貌 |
    | 置顶标记 | 置顶评论特殊标识 | 一眼识别重要评论 |
    | HTML 报告 | 深色主题交互式报告 | 离线保存/分享分析结果 |
    | 合并报告 | 多页合并,超3页自动折叠 | 一次导出全部评论分析 |
    
    ## 🔑 鉴权
    
    前往 [红狐hub](https://redfox.hk/settings/api-keys?source=github) 获取 API Key,通过以下方式配置:
    
    ```bash
    # 方式一:配置文件(如 OpenClaw 的 ~/.openclaw/openclaw.json)
    { "env": { "REDFOX_API_KEY": "ak_xxxx..." } }
    
    # 方式二:终端环境变量
    export REDFOX_API_KEY="ak_xxxx..."
    ```
    
    ## 🔄 工作流程
    
    ### Step 1:理解用户意图,提取 opusId
    
    **⚠️ 核心规则:用户提供作品链接,Agent 从链接中提取 opusId。**
    
    - 用户提供作品链接(如 `https://www.kuaishou.com/short-video/3x4ibfzs5e68yxu`),Agent 从链接中提取 opusId
    - 用户也可能直接提供 opusId(如 `3x4ibfzs5e68yxu`),此时直接使用
    - 若用户未提供作品链接,主动询问:「请提供快手作品链接」
    - 若用户在上一轮对话中查询过某作品的数据,且本轮输入模糊(如"下一页"、"评论分析"),沿用上一轮的 opusId
    
    ### Step 2:调用评论获取脚本(自动生成 HTML)
    
    **⚠️ 每次调用仅请求一页数据(一次 API 请求),不可擅自发起多次调用拉取多页。**
    
    **脚本每次调用自动生成 HTML 报告**(含占位符,未回填分析数据)。终端展示与 HTML 基于**同一次 API 调用**,确保数据一致。
    
    ```bash
    python3 ~/.agents/skills/kuaishou-comment/scripts/kuaishou_comment_search.py "<opusId>" [--cursor <cursor>] [--page <page>]
    ```
    
    **参数说明:**
    
    | 参数 | 说明 | 默认值 |
    |------|------|--------|
    | `opusId` | 快手作品 opusId(必填) | — |
    | `--cursor` | 游标,首页传空字符串,次页传上一页返回的 nextCursor | "" |
    | `--page` | 当前页码(仅用于 HTML 文件名和输出标记) | 1 |
    | `--output-dir` | HTML 输出目录 | ~/Downloads/QoderReports |
    
    脚本返回 JSON 字段详见下方评论字段表。
    
    > **注意:** HTML 报告此时仅含评论原始数据,分析占位符待用户确认后回填。
    
    ### Step 3:对话中展示评论数据 + AI 总结
    
    **⚠️ 每次操作仅调用一次 API,获取一页数据。**
    
    #### A1. 告知查询范围
    
    > 📊 作品「**{opusId}**」共获取 **N 条**评论(第 {page} 页),以下是详细数据:
    
    #### A2. 渲染评论表格(展示当前页全部评论)
    
    **格式规则:**
    - 评论人列只显示昵称,不展示头像、不生成超链接
    - 评论内容超过 40 字截断加 ...
    - 时间格式化为 MM-DD HH:MM
    - 置顶评论在昵称后加 📌 标记(整行加粗)
    - like_count / reply_count 数字 ≥ 10000 使用 x.xw 格式
    - 每页全部展示,不得截断
    
    #### A3. AI 评论总结(⚠️ 每次查询(含翻页)必须输出)
    
    **首页**:基于当前页评论,四维情感分析。
    
    **翻页后**:基于目前已获取的所有页面累计数据综合分析,标注累计总条数。
    
    **分析前需理解快手社区文化**(老铁文化、表情符号语义、"奥利给""双击"等特有表达)。
    
    > ## 📈 评论总结分析(基于 {total} 条评论)
    >
    > ### ✅ 积极评价({positive_ratio}%)
    > - {要点,引用代表评论关键词}
    >
    > ### ⚠️ 负面评价({negative_ratio}%)
    > - {要点}
    >
    > ### 💡 用户需求({demand_ratio}%)
    > - {要点}
    >
    > ### 🔍 竞品对比舆情({competitor_ratio}%)
    > - {仅当提及竞品时输出,否则输出「未提及竞品」}
    
    **分析要求:**
    - 每条要点引用代表评论关键词/短语
    - 百分比为该类型评论占比,四类总和可能超 100%
    - 必须理解快手社区文化
    
    #### A4. 翻页提示(⚠️ 紧接在 A3 之后)
    
    - 若 has_next 为 true:`📄 当前第 {page} 页(共 {total_fetched} 条)。回复「下一页」继续查看。`
    - 若 has_next 为 false:`📄 当前第 {page} 页,已无更多数据。`
    
    **⚠️ A1~A4 必须在同一轮输出中连续完成,不可省略任何一步。**
    
    A4 输出完毕后,**询问用户是否需要生成 HTML 可视化报告**:
    
    > 📊 是否需要生成 HTML 可视化报告?
    
    **若用户确认**,根据已浏览页数选择方式:
    
    ---
    
    #### 仅 1 页 → 单页 HTML(backfill_html.py)
    
    HTML 文件已在 Step 2 生成,直接回填分析数据并打开:
    
    ```bash
    python3 ~/.agents/skills/kuaishou-comment/scripts/backfill_html.py "<html_path>" --analysis-json '<分析JSON>'
    open "<html_path>"
    ```
    
    ---
    
    #### 2 页及以上 → 合并报告(consolidate_report.py)
    
    收集所有已浏览页面的 JSON 数据,生成一份包含**全部评论和累计分析**的完整 HTML。按页码分区展示,**超过 3 页时自动折叠**,提示用户点击展开。
    
    ```bash
    python3 ~/.agents/skills/kuaishou-comment/scripts/consolidate_report.py "<opusId>" \
      --pages-json '[{"page":1,"total":31,"comments":[...]},{"page":2,"total":20,"comments":[...]}]' \
      --analysis-json '<累计分析JSON>'
    open "<html_path>"
    ```
    
    | 参数 | 说明 |
    |------|------|
    | opusId | 快手作品 opusId(位置参数) |
    | --pages-json | 多页数据 JSON 数组,每项含 page、total、comments |
    | --analysis-json | 累计分析 JSON(字段同 backfill) |
    
    > pages 数据从各次脚本调用输出中收集;累计分析基于 A3 翻页后综合分析。
    
    ---
    
    **分析 JSON 字段说明:**
    
    | 字段 | 类型 | 说明 |
    |------|------|------|
    | positive_ratio | string | 积极评价占比(纯数字,如 "62",模板自动追加 %) |
    | negative_ratio | string | 负面评价占比 |
    | demand_ratio | string | 用户需求占比 |
    | competitor_ratio | string | 竞品对比占比 |
    | positive_summary | string | 积极评价摘要(HTML ul 格式) |
    | negative_summary | string | 负面评价摘要 |
    | demand_summary | string | 用户需求摘要 |
    | competitor_summary | string | 竞品对比摘要 |
    
    ### Step 4:翻页处理(用户回复「下一页」等时)
    
    1. 沿用 opusId
    2. 使用上一页的 nextCursor
    3. 重新调用脚本:`python3 ~/.agents/skills/kuaishou-comment/scripts/kuaishou_comment_search.py "<opusId>" --cursor "<nextCursor>" --page <page>`
    4. 完整执行 A1~A4,A3 基于累计综合分析
    5. A4 后询问是否需要 HTML
    
    **翻页规则:** has_next true → 用 nextCursor 翻页;false → 已无更多。cursor 原样传递,不可修改。
    
    ### Step 5:错误处理
    
    | 错误类型 | 处理方式 |
    |---------|---------|
    | 无 API Key | 提示配置 REDFOX_API_KEY |
    | 作品链接无效 | 提示「未找到该作品的评论,请检查作品链接是否正确」 |
    | 接口返回错误 | 显示错误码和错误信息 |
    | 获取 0 条评论 | 提示「该作品暂无评论」 |
    | 网络请求超时 | 提示「网络请求超时,请稍后重试」 |
    
    ---
    
    ## 📋 依赖
    
    脚本使用 urllib(Python 标准库),无需额外安装依赖。
    
    ---
    
    ## 🎯 使用示例
    
    **示例 1:查看指定作品的评论**
    ```
    用户:查看快手作品 3x4ibfzs5e68yxu 的评论
    助手:调用脚本 → 展示当前页 + AI总结 → 询问HTML → backfill → open
    ```
    
    **示例 2:通过链接查询**
    ```
    用户:https://www.kuaishou.com/short-video/3x4ibfzs5e68yxu 这个作品的评论怎么样
    助手:提取 opusId → 调用脚本 → 展示分析 → 询问HTML
    ```
    
    **示例 3:翻页后合并导出**
    ```
    用户:下一页 → 下一页 → 生成html
    助手:收集3页JSON → consolidate_report.py → 1个HTML含全部评论+折叠 → open
    ```
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related