douyin-hot-trend
专注于获取抖音最新的热榜数据,每小时更新,包含热点事件、热度值和跳转链接;支持查询近7天、近30天历史热榜,并支持订阅定时推送。
Install
npx skills add https://github.com/redfox-data/redfox-community/tree/main/skills/douyin-hot-trend
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install redfox-data-redfox-community@llmmart
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
抖音热榜神器 / douyin-hot-trend
简介
实时追踪抖音热点、挖掘爆款规律,帮助内容创作者和运营者高效蹭热点、找选题的智能热榜工具。
核心价值
- 每小时自动更新抖音 TOP 50 榜单,热度值与跳转链接一键可见
- 覆盖近 7 天、近 30 天历史热榜,随时回溯过往热点演变
- 从创作者视角自动生成选题机会、标题套路与趋势预判
- 支持任意两个时间点热榜对比,清晰标注新进榜与掉榜话题
- 支持每小时或每日定时推送,无需手动触发
适用对象
- 🎬 短视频创作者 — 每天快速锁定热点方向,缩短选题时间
- 📣 MCN 机构运营 — 统一监控平台趋势,高效指导达人内容策略
- 🏷️ 品牌营销人员 — 发现可借势话题,提升热点响应速度
- 📚 运营新手 — 学习爆款标题套路,快速建立内容感知
功能特性
核心功能
- 实时热榜查询:获取抖音当前 TOP 50 热榜,包含排名、热度值、话题标题和跳转链接,每 60 分钟刷新
- 历史热榜回溯:支持查询近 7 天或近 30 天历史数据,可按日期指定查看特定某天
- 热榜对比:对比任意两个时间点的热榜排名与热度变化,自动标注新进榜与掉榜话题
- 创作者洞察报告:热榜展示后自动输出爆款选题机会、标题套路拆解、趋势预判与行动建议
- 可视化报告导出:一键生成紫色极简风格 HTML 页面,支持导出 PDF,每条话题可点击跳转
- 定时订阅推送:支持每小时或每日定时推送,自动追踪热点变化
密钥获取与安全说明
- 本技能需要使用环境变量:
REDFOX_API_KEY。 REDFOX_API_KEY由 红狐 hub (https://redfox.hk)提供。- 请前往 红狐 hub 注册账号,获取
REDFOX_API_KEY。 - 配置设备环境变量
REDFOX_API_KEY后使用本技能。 - 在提供密钥前,请先确认密钥来源、可用范围、有效期及是否支持重置/撤销。
- 禁止在代码、提示词、日志或输出文件中硬编码/明文暴露密钥。
使用指南
直接用自然语言描述需求,无需记忆命令。
常用说法速查
| 意图 | 示例话术 | 效果 |
|---|---|---|
| 查看实时热榜 | 抖音热榜 / 今日热榜 | 展示当前 TOP 20,含热度值与话题链接,附创作者洞察报告 |
| 查看昨日热榜 | 昨日热榜 | 查询昨天全天热榜数据 |
| 查看历史热榜 | 近7天热榜 / 近30天热榜 | 按时间范围回溯历史热点 |
| 查看指定日期 | 5月15日热榜 | 查询特定日期的榜单数据 |
| 加载完整榜单 | 继续加载 / 加载更多 | 从 TOP 20 扩展至完整 TOP 50 |
| 对比热榜变化 | 对比昨天和今天的热榜 | 输出两日热榜差异,标注新进榜与掉榜话题 |
| 订阅推送 | 订阅每日热榜推送 | 设置定时自动推送,每日获取最新热榜 |
| 取消订阅 | 取消订阅 | 停止定时推送 |
输出示例
查询「今日热榜」后,你将收到:
- 热榜表格:序号、话题标题、热度值、跳转链接(TOP 20,可继续加载至 50)
- 创作者洞察报告:
- 🔥 爆款选题机会(可迁移话题与创作方向)
- 🎯 标题套路拆解(情绪词、句式结构)
- 📈 趋势预判(哪些话题正在上升/下降)
- 💡 行动建议(可执行的内容策略)
- 可视化报告:自动生成 HTML 页面,支持导出 PDF
使用场景
| 场景 | 角色 | 示例问法 | 收益 |
|---|---|---|---|
| 每日选题灵感 | 短视频创作者 | 「今日热榜」 | 快速锁定热点方向,获取可迁移选题与标题公式 |
| 热点趋势监控 | MCN 运营人员 | 「近7天热榜」 | 掌握一周热点演变规律,为达人提供内容策略参考 |
| 热点借势营销 | 品牌营销经理 | 「对比本周热榜变化」 | 发现持续发酵话题,提前布局品牌借势内容 |
| 运营学习研究 | 短视频新手 | 「今日热榜,帮我分析标题套路」 | 学习爆款句式结构,快速建立内容感知 |
Skill manifest
抖音热榜
简介
抖音热榜是一款实时追踪抖音平台热点趋势的数据工具,对接 红狐Hub 数据 API,每小时更新热榜内容,并提供创作者视角的深度分析。
通过简单的自然语言指令,你可以:
- 📊 实时热榜查询:每 60 分钟抓取抖音 TOP 50 榜单,同步热度值与跳转链接
- 📅 历史热榜回溯:覆盖近 7 天、近 30 天历史数据,支持按日期与关键词检索
- 🔀 热榜数据对比:对比任意两个时间点(如昨天 vs 今天)的热榜变化
- 💡 深度洞察分析:从创作者视角提供选题机会、标题套路与趋势预判
- 🔔 个性化订阅:支持每小时或每日定时推送热榜数据
适用于内容创作者、短视频运营、MCN 机构、品牌营销人员等需要追踪抖音热点、寻找创作灵感、制定内容策略的场景。
技术基础:Python 3.x + requests 库,通过 红狐Hub APIKey获取数据。
功能特性
🎯 核心功能
- 📊 实时热榜:获取抖音当前 TOP 50 热榜,每小时刷新,展示排名、热度值、话题标题和跳转链接
- 📅 历史回溯:支持查询近 7 天或近 30 天历史热榜,最长覆盖 30 天
- 💡 创作者洞察:自动生成选题机会分析、标题套路拆解、趋势预判与行动建议
- 📄 可视化报告:一键生成紫色极简风格 HTML 页面,支持导出 PDF,每条记录可点击跳转
- 🔔 订阅推送:支持每小时或每日定时推送,自动追踪热点变化
✨ 特色亮点
- ⚡ 自然语言交互:输入「今日热榜」「近7天热榜」等即可查询,无需记忆命令参数
- 🔒 三级鉴权回退:API Key 优先从环境变量读取,自动回退到 Shell 配置文件
- ✅ 数据一致性:表格、洞察、HTML、PDF 全链路数据一致,不做加工或美化
- 🎬 创作者视角:每条洞察都回答「怎么用」,给出可执行的行动建议
一键安装
前置条件
- 已安装 Python 3.x 及
requests库 - 已注册 红狐Hub官网 账号并获取 API Key(格式
ak_xxxxxxxx) - 新注册用户将获赠免费积分,可立即开始使用
安装方式
方式一:WorkBuddy(龙虾)技能安装(推荐)
- 将
douyin-hot-trend技能文件夹复制到 WorkBuddy 的 skills 目录下 - 在 WorkBuddy 对话中直接说「抖音热榜」或「今日热榜」,Agent 将自动加载本技能
- 配置 API Key(见下方「环境变量配置」)
- 安装 Python 依赖:
pip install requests
方式二:Cursor / 其他 Agent 环境手动安装
- 将技能文件夹放置到对应环境的 skills 目录
- 确保 Agent 可读取
SKILL.md与references/core_workflow.md - 配置
REDFOX_API_KEY环境变量 - 执行
pip install requests
环境变量配置
| 变量名 | 必填 | 说明 |
|---|---|---|
REDFOX_API_KEY |
是 | 红狐Hub API 访问密钥,格式 ak_xxxxxxxx |
配置方式(任选其一):
# 方式一:直接设置环境变量(推荐)
export REDFOX_API_KEY=ak_xxxxxxxx
# 方式二:写入 Shell 配置文件(~/.bashrc / ~/.bash_profile / ~/.zshrc)
echo 'export REDFOX_API_KEY=ak_xxxxxxxx' >> ~/.bashrc
source ~/.bashrc
若未配置环境变量,技能将自动从 Shell 配置文件读取;若仍未获取到,会在运行时提示配置。
在 WorkBuddy 中配置 Key:可在系统环境变量中设置 REDFOX_API_KEY,或在 Shell 配置文件中写入后重启 WorkBuddy,无需在每次对话中手动传入。
使用指南
基础使用
1. 查看实时热榜
告诉助手你想查看当前抖音热点:
用户:抖音热榜 助手:为您展示抖音实时热榜 TOP 20(含排名、热度值、话题链接),并附创作者洞察报告。
2. 查看历史热榜
查询指定时间范围的历史数据:
用户:近7天热榜 助手:为您展示近 7 天抖音历史热榜,支持按日期回溯热点演变。
用户:4月15日热榜 助手:为您查询 4 月 15 日当天的热榜数据。
3. 加载完整榜单
默认展示 TOP 20,可继续加载至 TOP 50:
用户:继续加载 助手:为您展示 TOP 21–50,并生成包含完整 TOP 50 的 HTML 报告。
高级使用
1. 创作者洞察
热榜展示后自动输出深度分析:
用户:今日热榜 助手:(展示表格后)输出爆款选题机会、标题套路破解、趋势预判与行动建议。
2. 热榜对比
对比两个时间点的热榜变化:
用户:对比昨天和今天的热榜 助手:为您对比两日热榜排名与热度变化,标注新进榜与掉榜话题。
3. 订阅推送
设置定时自动推送:
用户:订阅每日热榜推送 助手:已设置每日推送,将在指定时间自动推送 TOP 50 完整热榜数据。
用户:取消订阅 助手:已取消定时推送。
4. 生成报告
每次查询自动生成可视化报告:
用户:今日热榜 助手:(查询完成后)已生成 HTML 页面与 PDF 文件,数据与表格展示完全一致,支持点击跳转。
常用指令速查
| 指令 | 功能 |
|---|---|
| 抖音热榜 / 今日热榜 | 查询实时热榜 TOP 20 |
| 昨日热榜 | 查询昨日热榜 |
| 近7天热榜 | 查询近 7 天历史热榜 |
| 近30天热榜 | 查询近 30 天历史热榜 |
| X月X日热榜 | 查询指定日期热榜 |
| 继续加载 / 加载更多 | 加载 TOP 21–50 完整榜单 |
| 订阅每日/每小时推送 | 设置定时推送 |
| 取消订阅 | 停止定时推送 |
使用场景
场景一:内容创作者找选题
角色:抖音短视频创作者
需求:每天快速了解平台热点,找到适合自己赛道的创作方向
使用方式:
- 每天早晨说「今日热榜」,获取最新热点
- 查看创作者洞察报告,获取选题建议和标题公式
- 直接套用可迁移选题,快速产出内容
预期收益:缩短选题时间,提高内容命中率
场景二:MCN 机构运营管理
角色:MCN 运营人员
需求:监控平台热点趋势,为旗下达人提供选题指导和内容策略
使用方式:
- 订阅每日热榜推送,自动获取最新热点
- 查看历史热榜,分析热点演变规律
- 将洞察报告分享给达人团队,指导内容创作
预期收益:提升团队内容策略的时效性和精准度
场景三:品牌营销热点借势
角色:品牌营销经理
需求:及时发现可借势的热点话题,制定蹭热点营销方案
使用方式:
- 关注每日热榜,筛选与品牌调性匹配的热点
- 分析趋势预判,提前布局内容
- 导出 HTML/PDF 报告,用于团队沟通和方案汇报
预期收益:提升品牌热点的响应速度和借势效果
场景四:短视频运营学习研究
角色:短视频运营新手
需求:学习爆款内容的创作规律,提升运营能力
使用方式:
- 定期查看热榜和创作者洞察
- 学习标题套路和情绪触发词
- 模仿可迁移选题进行练习
预期收益:快速建立内容 sense,掌握爆款创作方法论
项目架构
目录结构
douyin-hot-trend/
├── SKILL.md # 技能说明文档(当前文件)
├── references/
│ └── core_workflow.md # Agent 核心工作流指令
├── scripts/
│ ├── hotspot_fetcher.py # 热榜数据获取脚本
│ └── gen_douyin_hot_html.py # HTML 可视化报告生成脚本
└── assets/
└── douyin_hot_trend_template.html # HTML 页面模板
核心模块说明
| 模块 | 文件 | 职责 |
|---|---|---|
| 数据获取 | hotspot_fetcher.py |
调用 红狐Hub API 获取抖音热榜 JSON,支持实时与历史查询 |
| 报告生成 | gen_douyin_hot_html.py |
将热榜数据渲染为紫色极简风格 HTML,支持导出 PDF |
| 页面模板 | douyin_hot_trend_template.html |
独立 HTML 模板,支持占位符快速替换生成 |
技术栈
| 类别 | 说明 |
|---|---|
| 运行环境 | Python 3.x |
| HTTP 请求 | 原生 requests 库 |
| 认证方式 | X-API-KEY 请求头,三级回退(环境变量 → Shell 配置 → 提示配置) |
| 数据来源 | 红狐Hub API |
| 部署平台 | WorkBuddy / Cursor 等 Agent 环境 |
常见问答
安装相关问题
Q1: 运行时提示「缺少 REDFOX_API_KEY 配置」怎么办?
A: 请按以下步骤排查:
- 确认已注册 红狐Hub 账号并在个人中心获取 API Key
- 设置环境变量:
export REDFOX_API_KEY=ak_xxxxxxxx - 或写入 Shell 配置文件后执行
source ~/.bashrc使其生效 - 确认 API Key 格式正确,以
ak_开头
Q2: 需要安装哪些 Python 依赖?
A: 仅需 requests 库:pip install requests
Q3: 如何在 WorkBuddy(龙虾)中启用本技能?
A: 将技能文件夹放入 WorkBuddy 的 skills 目录,配置好 REDFOX_API_KEY 后,在对话中说「抖音热榜」即可触发。Agent 将按 references/core_workflow.md 执行完整工作流。
使用相关问题
Q4: 热榜数据多久更新一次?
A: 每小时更新一次。每次查询都会调用 API 获取最新数据,不依赖本地缓存。
Q5: 可以查询多久之前的历史数据?
A: 最长支持查询近 30 天的历史热榜。超过 30 天的数据暂不支持。
故障排除
Q6: API 调用失败怎么办?
A: 请按以下顺序排查:
- 检查网络连接,确认可以访问
https://redfox.hk?source=github - 确认 API Key 未过期,账户积分是否充足
- 检查环境变量:
echo $REDFOX_API_KEY - 稍后重试,API 服务可能存在临时波动
Q7: 订阅推送没有收到怎么办?
A: 确认订阅已成功设置。如需重新设置,说「取消订阅」后重新订阅。如仍有问题,检查WorkBuddy等系统的自动化任务是否正常运行。
Q8: HTML 报告预览不成功或显示空白怎么办?
A: 请按以下方式处理:
- 确认 HTML 文件已成功生成(脚本会输出
✅ 已生成提示) - 直接双击打开交付的 HTML 文件,用 Chrome/Edge 浏览器查看,不依赖WorkBuddy等系统内置预览
- 若文件已交付但内置预览空白,属于已知限制——Windows 中文用户名路径可能导致预览组件兼容性问题,直接用浏览器打开即可正常显示
安全与许可
Q9: API Key 如何安全存储?
A: 建议通过环境变量或 Shell 配置文件存储,不要将 Key 写入代码仓库或公开分享。本技能支持三级鉴权回退,优先读取环境变量,避免在对话中明文传递。
Q10: 数据来源与使用许可?
A: 热榜数据来自 红狐Hub 官方 API,使用时须遵守 红狐Hub 平台服务条款及抖音平台相关规定。本技能仅作数据展示与分析辅助,不保证数据的商业用途合规性。
获取帮助
如有其他问题,可通过以下方式获取帮助:
- 📖 查阅 Agent 执行参考:
references/core_workflow.md - 🌐 红狐Hub 官网:https://redfox.hk?source=github
- 📧 联系 红狐Hub 平台客服获取 API 相关问题支持
Agent 执行参考:完整的操作步骤、输出格式、数据规则等执行层指令,请查阅 references/core_workflow.md。
Files (redfox-community)
-
references
-
core_workflow.md 11.3 KB
# 核心工作流(Agent 执行参考) 本文档为 Agent 执行层的详细工作流指令,包含数据获取、展示、分析、订阅、HTML 生成等完整步骤。 ## 任务目标 - 获取抖音平台热榜数据,并提供创作者视角的深度洞察 - 触发条件:用户询问抖音热榜、热门话题、热搜榜单、历史热榜、订阅热榜推送等 ## 操作步骤 ### 1. 获取热榜数据 **Python 执行说明**: - 优先使用系统默认 `python` 命令 - 若 `python` 不可用(Windows Git Bash 常见),使用 WorkBuddy 管理的 Python 全路径:`"C:/Users/马祯/.workbuddy/binaries/python/versions/3.13.12/python.exe"` - 始终先 `cd` 到技能根目录再执行 #### 1.1 实时热榜(默认) ```bash cd "C:/Users/马祯/.workbuddy/skills/douyin-hot-trend" && python scripts/hotspot_fetcher.py ``` #### 1.2 历史热榜查询 支持查询近7天、近30天的历史热榜数据: ```bash # 查询昨日热榜(假设今天是2026-04-16) cd "C:/Users/马祯/.workbuddy/skills/douyin-hot-trend" && python scripts/hotspot_fetcher.py --start-date 2026-04-15 --end-date 2026-04-16 # 查询近7天热榜(假设今天是2026-04-16) cd "C:/Users/马祯/.workbuddy/skills/douyin-hot-trend" && python scripts/hotspot_fetcher.py --start-date 2026-04-09 --end-date 2026-04-16 # 查询近30天热榜(假设今天是2026-04-16) cd "C:/Users/马祯/.workbuddy/skills/douyin-hot-trend" && python scripts/hotspot_fetcher.py --start-date 2026-03-17 --end-date 2026-04-16 # 查询4月1日热榜 cd "C:/Users/马祯/.workbuddy/skills/douyin-hot-trend" && python scripts/hotspot_fetcher.py --start-date 2026-04-01 --end-date 2026-04-02 ``` **日期范围规则**: - 日期范围是 **[start_date, end_date)** 左闭右开区间 - 例如:`start-date 2026-04-01 --end-date 2026-04-02` 查询的是4月1日当天的数据 - 例如:`start-date 2026-04-09 --end-date 2026-04-16` 查询的是4月9日至4月15日共7天的数据 **参数说明**: - `--start-date`:开始日期(包含),格式 YYYY-MM-DD - `--end-date`:结束日期(不包含),格式 YYYY-MM-DD - `--days`:查询天数,自动计算日期范围(end_date为今天) - **最长查询范围:30天** #### 1.3 意图判断逻辑 根据用户意图自动选择查询方式(假设今天日期为T): | 用户表达 | start_date | end_date | 查询范围 | |---------|-----------|----------|---------| | "今日热榜" / "最新热榜" / "热榜" | 无(实时) | 无(实时) | 实时 | | "昨日热榜" / "昨天热榜" | T-1 | T | 昨日当天 | | "近7天热榜" / "一周热榜" | T-7 | T | 近7天 | | "近30天热榜" / "本月热榜" | T-30 | T | 近30天 | | "X月X日热榜" | X月X日 | X月X日+1 | 指定日期当天 | ### 2. 展示热榜数据表格 将脚本返回的JSON数据转换为表格形式展示。 **标题格式**: 实时热榜:`抖音实时热榜(2026-04-14 16:00 每小时更新)` 历史热榜:`抖音历史热榜(2026-04-14 至 2026-04-15)` **表格格式**(默认展示TOP20数据): | 排名 | 热度值 | 话题 | 核心内容 | |-----|-------|------|---------| **表格绘制规则**: 1. 排名:默认 `TOP01` 到 `TOP20`(双数字符);加载更多 `TOP21` 到 `TOP50` 2. 热度值:保留一位小数,单位统一为 `w`(小写),示例 `1109.6w` 3. 话题:使用 Markdown 链接格式 `[标题](URL)` 4. 核心内容:30-80字,概括话题主要内容 **加载更多**: 表格下方展示: > 抖音实时热榜为你提供TOP50的数据,是否继续加载剩余30条? - 确认后仅输出 TOP21-TOP50,不重复 TOP1-20 - 确认后必须生成新的 HTML 文件,包含完整 TOP50 数据 ### 3. 创作者洞察报告 展示数据后自动输出创作者视角的深度洞察: #### 3.1 爆款选题机会 分析热榜内容的共同规律,提供可迁移的选题建议。 输出格式: ``` 📌 爆款选题机会 发现:[核心发现] - 数据支撑:[具体数据] - 核心公式:[拆解出的公式] 🔄 可迁移选题: · 美妆赛道:[具体选题建议] · 穿搭赛道:[具体选题建议] · 其他赛道:[具体选题建议] ``` #### 3.2 标题套路破解 提炼爆款标题模式和情绪触发词。 输出格式: ``` ✏️ 标题套路破解 爆款标题模式TOP3: 1. [类型名称]:[示例] 2. [类型名称]:[示例] 3. [类型名称]:[示例] 立即可用的标题公式: · "用[方法],[效果]" → 例:用万能旅行拍照姿势美美出片 · "耗时[时间],拍下[成果]" → 例:耗时三年拍下古诗词里的中国 · "原来[认知],真的存在" → 例:原来古诗词里的河南真的存在 情绪触发词: [高频词列表] ``` #### 3.3 趋势预判与行动建议 基于热榜数据给出前瞻性判断。 输出格式: ``` 📈 趋势预判 一、[预判点1] [具体分析内容和依据] 行动建议:[具体建议] 二、[预判点2] [具体分析内容和依据] 行动建议:[具体建议] 三、[预判点3] [具体分析内容和依据] 行动建议:[具体建议] ``` #### 3.4 分析原则 - 基于实际数据,不编造 - 给出可执行的行动建议,不泛泛而谈 - 从创作者视角出发,每条洞察都要回答"怎么用" - 保持专业但易懂,避免术语堆砌 ### 4. 询问订阅 分析完成后必须主动询问是否需要订阅。 ``` 🔔 订阅服务 是否需要订阅每日/每小时热榜推送? 1. 每小时推送 - 实时追踪热点变化(默认推送TOP50完整数据) 2. 每日推送 - 每天早/晚获取一次热榜汇总(默认推送TOP50完整数据) 3. 暂不需要 - 仅本次查询 请回复数字或"取消",如有其他推送时间偏好请说明。 ``` **订阅处理流程**: - 用户选择1(每小时推送):记录偏好,后续每小时自动推送TOP50数据 - 用户选择2(每日推送):询问具体推送时间(早/晚),记录偏好,推送TOP50数据 - 用户选择3或"取消":结束本次交互,不记录 - 用户有其他偏好:灵活记录并确认 订阅数据默认推送TOP50完整数据;如用户特别要求TOP20,按用户要求执行。 ### 5. 生成热榜HTML页面(强制执行) HTML文件生成是必须执行的强制步骤,不等待用户回复,立即执行。 **执行顺序**:获取数据(保存JSON) → 展示表格 → 创作者洞察 → 询问订阅 → 立即执行HTML生成(从JSON读取) **关键优化**:HTML生成器通过 `--json-file` 参数直接读取第一步保存的JSON文件,不再重复调用API。确保 API 调用次数始终为 1 次。 **触发场景**: | 场景 | HTML数据范围 | 文件命名 | |-----|------------|---------| | 查询实时热榜 | TOP20(严格20条) | `douyin_hot_YYYYMMDD_HHMM.html` | | 查询历史热榜 | TOP20(严格20条) | `douyin_hot_YYYYMMDD_YYYYMMDD.html` | | 用户加载更多 | TOP50(严格50条) | `douyin_hot_top50_YYYYMMDD_HHMM.html` | **HTML数据展示规则**: - 默认展示TOP20,仅用户明确要求时展示TOP50 - 数据条数严格控制:TOP20模式20条,TOP50模式50条 - 禁止自动扩展数据范围 **执行流程**(两步,共1次API调用): ```bash # 步骤1:获取数据并保存为JSON文件 cd "C:/Users/马祯/.workbuddy/skills/douyin-hot-trend" && python scripts/hotspot_fetcher.py > scripts/temp_hot_data.json # 步骤2:从JSON文件生成HTML(不再调用API) # 实时热榜(TOP20) cd "C:/Users/马祯/.workbuddy/skills/douyin-hot-trend" && python scripts/gen_douyin_hot_html.py --json-file scripts/temp_hot_data.json --output scripts/douyin_hot_20260529_1000.html # 加载更多(TOP50) cd "C:/Users/马祯/.workbuddy/skills/douyin-hot-trend" && python scripts/gen_douyin_hot_html.py --json-file scripts/temp_hot_data.json --top 50 --output scripts/douyin_hot_top50_20260529_1000.html ``` **Agent执行注意事项**: - 第一步获取数据时,将 `hotspot_fetcher.py` 的 stdout 输出重定向保存到临时JSON文件 - 第二步 HTML 生成时,必须使用 `--json-file` 参数指向临时JSON文件,禁止省略该参数 - 临时 JSON 文件可在 HTML 生成后保留或清理,不影响功能 **文件命名规则**: - 实时热榜:`douyin_hot_YYYYMMDD_HHMM.html` - 历史热榜:`douyin_hot_起始日期_结束日期.html` - 加载更多:`douyin_hot_top50_YYYYMMDD_HHMM.html` **加载更多场景**:仅输出TOP21-TOP50表格,立即生成新HTML文件(含完整TOP50)。 **HTML输出要求**: - 必须直接输出完整HTML文件内容(使用代码块展示HTML源码) - 同时告知文件路径 - 无论实时还是历史查询,都必须输出完整HTML **HTML 交付与预览流程**(强制执行): 1. **生成 HTML**:执行 `gen_douyin_hot_html.py` 脚本,确认 stderr 输出 `✅ 已生成` 和 `📊 共 X 条` 2. **尝试预览**:调用 `preview_url` 工具,传入 `file:///C:/Users/马祯/.workbuddy/skills/douyin-hot-trend/scripts/文件名.html` 3. **交付文件**:调用 `deliver_attachments` 工具,将 HTML 文件作为附件交付给用户 4. **预览失败备用方案**:若 `preview_url` 因中文路径或 `file://` 协议限制未能正常渲染,提示用户直接双击打开交付的 HTML 文件。不要反复重试 `preview_url` **预览注意事项**: - Windows 中文用户名路径(如 `马祯`)可能导致 `file://` 协议预览失败,这是已知限制 - `deliver_attachments` 交付的文件用户可直接下载并在浏览器中打开,不受路径编码影响 - 优先确保文件交付成功,预览仅作为辅助手段 **PDF输出要求**: - 必须输出PDF文件 - 生成方式:先生成HTML,再转换为PDF - PDF内容支持点击跳转到对应话题页面 **数据一致性要求**: - HTML数据必须完全来自脚本执行的API返回数据 - 禁止修改排名、热度值、话题标题、跳转链接 - 禁止重新排序、美化或编造数据 - HTML中每条数据必须与表格输出完全一致 **HTML统计数据**: - 话题总数 = 实际展示数据条数(TOP20或TOP50) - 最高热度 = 所有展示热度值的最大值 - 平均热度 = 所有展示热度值的平均值 - 禁止编造统计数据 ### 6. 可选操作 - 用户可点击标题直接跳转到对应热点页面 - 可根据热度值排序或筛选特定话题 - 可随时发送"取消订阅"停止推送 ## 资源索引 - 数据获取脚本:`scripts/hotspot_fetcher.py` — 获取抖音热榜JSON数据 - HTML生成脚本:`scripts/gen_douyin_hot_html.py` — 生成热榜可视化HTML页面 - HTML模板文件:`assets/douyin_hot_trend_template.html` — HTML页面模板,支持占位符快速生成 ## 模板使用说明 `douyin_hot_trend_template.html` 支持以下占位符: | 占位符 | 说明 | 示例值 | |-------|------|-------| | `{{PAGE_TITLE}}` | 页面标题 | 抖音实时热榜 | | `{{FETCH_TIME}}` | 获取时间 | 2026-04-17 10:00:00 | | `{{HOT_LIST_DATA}}` | 热榜数据JSON | `[{...}, {...}]` | 将占位符替换为实际数据即可生成完整HTML页面。 ## 注意事项 - API调用需要网络连接 - 热榜数据实时更新,每次调用获取最新数据 - 历史热榜最长查询范围为30天 - 如遇API调用失败,提示用户稍后重试 - 订阅偏好需要用户明确确认后记录 - 分析必须基于实际数据,给出可执行的行动建议
-
-
scripts
-
gen_douyin_hot_html.py 31.4 KB
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 抖音热榜HTML生成器 从JSON文件读取热榜数据,生成可独立打开的HTML页面。 用法: python gen_douyin_hot_html.py --json-file data.json --output output.html python gen_douyin_hot_html.py --json-file data.json --output output.html --top 50 数据来源优先级: 1. --json-file 参数:从指定JSON文件读取(推荐,避免重复API调用) 2. --start-date / --end-date / --days 参数:自行调用API获取(兼容旧用法) 样式特性: - 紫色系极简风格(#6c5ce7 / #a29bfe) - 卡片式表格(border-collapse: separate,每行独立圆角白卡) - TOP3 奖牌徽章 + 对应色竖线边框 - 4+ 序号深灰小字 - 热度值纯紫色 #6c5ce7 - 整行点击跳转(location.href,兼容 file:// 协议) - 导出 PDF 功能(仅截取内容区,不含按钮栏,单页 A4 自适应缩放) - 页面最大宽度 750px """ import json import sys import os import re from datetime import datetime, timedelta import requests def get_api_key(): """ 获取 REDFOX_API_KEY,按三级优先级回退: 1. 从当前设备环境变量 REDFOX_API_KEY 获取 2. 从 shell 配置文件(~/.bashrc / ~/.bash_profile / ~/.zshrc)中读取 3. 提示用户配置 Returns: str: API Key 字符串 Raises: SystemExit: 未能获取到有效的 API Key """ # 第一级:从环境变量获取 api_key = os.getenv("REDFOX_API_KEY") if api_key and api_key.strip(): return api_key.strip() # 第二级:从 shell 配置文件读取 home = os.path.expanduser("~") shell_configs = [ os.path.join(home, ".bashrc"), os.path.join(home, ".bash_profile"), os.path.join(home, ".zshrc"), ] for config_path in shell_configs: if os.path.isfile(config_path): try: with open(config_path, "r", encoding="utf-8", errors="ignore") as f: content = f.read() match = re.search( r'export\s+REDFOX_API_KEY\s*=\s*["\']?([a-zA-Z0-9_]+)["\']?', content ) if match: api_key = match.group(1).strip() if api_key: return api_key except Exception: continue # 第三级:提示用户配置 raise ValueError( "缺少 REDFOX_API_KEY 配置。" "请设置环境变量 REDFOX_API_KEY=ak_xxxxxxxx," "或将其写入 shell 配置文件(~/.bashrc / ~/.bash_profile / ~/.zshrc)。" "访问 https://redfox.hk/login 注册账号,在个人中心获取 API Key。" ) def fetch_douyin_hotspot(start_date=None, end_date=None, days=None): """获取抖音热榜数据 - 使用原生 requests,API Key 三级回退""" # 获取 API Key(三级回退) credential = get_api_key() # 构建请求URL和参数 url = "https://redfox.hk/story/api/hotSpot/getListByPlatform" params = { "platform": 2, "source": "抖音热榜-GitHub" } query_type = "实时" if days: today = datetime.now().date() end_date_obj = today start_date_obj = today - timedelta(days=days) params["startDate"] = start_date_obj.strftime("%Y-%m-%d") params["endDate"] = end_date_obj.strftime("%Y-%m-%d") query_type = f"近{days}天" if start_date and end_date: params["startDate"] = start_date params["endDate"] = end_date query_type = f"{start_date} 至 {end_date}" # 构建请求头 headers = { "X-API-KEY": credential, "Accept": "application/json, text/plain, */*", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } response = requests.get(url, params=params, headers=headers, timeout=30) if response.status_code >= 400: raise Exception(f"HTTP请求失败: {response.status_code}, {response.text}") api_response = response.json() if isinstance(api_response, dict): data = api_response.get("data", api_response.get("list", [])) elif isinstance(api_response, list): data = api_response else: data = [] # 处理数据:去除标题中的所有空格(半角空格、全角空格、制表符、换行符等) for item in data: if 'title' in item and item['title']: item['title'] = ''.join(item['title'].split()) if 'word' in item and item['word']: item['word'] = ''.join(item['word'].split()) return { "fetch_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "query_type": query_type, "hot_list": data } def generate_desc(title, hot_count): """根据标题和热度值生成核心内容摘要(30-80字)""" import re desc = title hot_str = f"热度{hot_count}" # 核心内容生成规则 - 基于标题关键词匹配 if any(k in title for k in ['春天', '春日', '花开', '樱花', '踏青']): return f"春季相关话题持续升温,用户分享春日生活美好瞬间与旅行记录,展现春日美景与生活方式,引发大量互动讨论,当前{hot_str}" elif any(k in title for k in ['裙摆', '穿搭', '时尚', '美妆', '妆容', '造型']): return f"时尚穿搭类话题火爆,博主分享穿搭技巧与造型灵感,年轻用户积极参与模仿创作,带动相关话题持续走高,当前{hot_str}" elif any(k in title for k in ['海洋', '科技', '技术', '突破', '创新', '研发']): return f"硬核科技/工业成就引发全民关注,展现中国技术实力与发展成果,网友纷纷点赞转发表达民族自豪感,当前{hot_str}" elif any(k in title for k in ['骑马', '公主', '古装', '汉服', 'cosplay']): return f"古风/角色扮演类内容走红,创作者通过特色造型吸引关注,用户参与度高,评论区互动热烈,当前{hot_str}" elif any(k in title for k in ['对镜', '自拍', '拍照', '镜头', '摄影']): return f"摄影/自拍技巧类内容广受欢迎,创作者分享实用拍摄方法,帮助普通用户提升出片质量,传播度极高,当前{hot_str}" elif any(k in title for k in ['出游', '旅行', '旅游', '景点', '打卡']): return f"旅游出行话题热度攀升,各地景点迎来游客高峰,用户分享旅行攻略与见闻,激发更多人规划行程,当前{hot_str}" elif any(k in title for k in ['赖清德', '弹劾', '政治', '政策', '政府', '官员']): return f"时政类重大事件引发全网热议,各平台讨论量激增,用户密切关注事态发展,相关分析解读视频获得高播放,当前{hot_str}" elif any(k in title for k in ['房价', '楼市', '房贷', '购房', '经济', 'GDP', '股市', 'A股']): return f"财经/民生话题牵动大众神经,专业机构与个人投资者高度关注市场动态,各类解读分析内容刷屏,当前{hot_str}" elif any(k in title for k in ['电影', '剧集', '开播', '定档', '综艺', '选秀', '歌手']): return f"影视娱乐类话题霸榜,新作品/节目上线引发追剧热潮,明星动态与剧情讨论占据热搜前列,当前{hot_str}" elif any(k in title for k in ['游戏', '电竞', '比赛', '战队', '选手']): return f"游戏/电竞赛事话题火热,职业赛事精彩操作被广泛传播,玩家社区讨论氛围活跃,相关二创内容爆发式增长,当前{hot_str}" elif any(k in title for k in ['美食', '做饭', '食谱', '奶茶', '探店', '餐厅']): return f"美食类内容持续吸睛,创作者推荐美食做法与探店体验,激发用户尝试欲望与打卡热情,评论区求教程留言众多,当前{hot_str}" elif any(k in title for k in ['萌宠', '猫咪', '狗狗', '动物', '可爱']): return f"宠物/动物类治愈系内容广受喜爱,萌宠日常视频轻松获取百万播放,用户在评论区晒出自家毛孩子照片,互动率极高,当前{hot_str}" elif any(k in title for k in ['健身', '减肥', '运动', '瑜伽', '瘦身']): return f"健康运动话题受关注度提升,健身达人分享训练计划与饮食建议,激励大批用户开启锻炼模式,跟练打卡成风潮,当前{hot_str}" elif any(k in title for k in ['教育', '高考', '考研', '学校', '老师', '家长']): return f"教育相关话题引发家长群体强烈共鸣,升学政策与学习方法的讨论热度居高不下,干货分享型内容获大量收藏,当前{hot_str}" elif any(k in title for k in ['恋爱', '感情', '婚姻', '分手', '相亲']): return f"情感婚恋话题触动年轻人共鸣,真实故事分享与情感分析视频引发深度讨论,用户在评论区倾诉经历寻求建议,当前{hot_str}" elif any(k in title for k in ['职场', '工资', '面试', '辞职', '老板', '打工']): return f"职场话题直击打工人痛点,薪资待遇、工作体验等议题引发广泛共鸣,职场经验分享内容获高收藏转发,当前{hot_str}" else: # 兜底:基于标题长度智能扩展 return f"该话题在抖音平台引发广泛关注与讨论,大量创作者围绕此主题产出优质内容,用户互动活跃,相关视频播放量持续增长,当前{hot_str}" def generate_html(result, top_n=20): """生成HTML页面 - 紫色极简风格 Args: result: 热榜数据结果 top_n: 显示条数,默认20,可设为50 重要:只传递实际需要展示的数据到HTML,确保统计数据与展示数据一致 """ hot_list = result["hot_list"] fetch_time = result["fetch_time"] query_type = result["query_type"] # 限制显示条数 - 必须先截取,确保统计数据准确 top_n = min(top_n, 50) # 最大支持TOP50 # ⚠️ 关键:只保留实际需要展示的数据,确保HTML中统计数据与展示数据一致 hot_list = hot_list[:top_n] def fmt_hot_value(n): """格式化热度值 - 保持与表格显示一致""" n = int(n or 0) if n >= 100000000: return f"{n / 100000000:.1f}亿" if n >= 10000: # 保留一位小数,如 1109.6w return f"{n / 10000:.1f}w" return str(n) # 为每条数据生成核心内容摘要和格式化热度值 for item in hot_list: # 生成核心内容摘要 if not item.get('desc') and not item.get('excerpt'): title = item.get('title', '') or item.get('word', '') hot_count = item.get('hotCount', '') or item.get('hotValue', '0') item['_genDesc'] = generate_desc(title, fmt_hot_value(hot_count)) # 格式化热度值,确保HTML显示与智能体表格一致 hot_count = item.get('hotCount', '') or item.get('hotValue', '0') item['_fmtHeat'] = fmt_hot_value(hot_count) js_data = json.dumps(hot_list, ensure_ascii=False, indent=2) if query_type == "实时": page_title = "抖音实时热榜" else: page_title = f"抖音热榜({query_type})" html = f'''<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{page_title}</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> <style> * {{ margin: 0; padding: 0; box-sizing: border-box; }} body {{ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'PingFang SC', sans-serif; background: #f0f0f5; color: #333; line-height: 1.6; }} /* ===== 页面容器 - 最大宽度750px ===== */ .page-wrap {{ max-width: 750px; margin: 0 auto; padding: 16px 16px 32px; }} /* ===== 导出按钮栏 - 不参与PDF导出 ===== */ .export-bar {{ position: sticky; top: 0; z-index: 100; display: flex; justify-content: flex-end; padding: 10px 0 12px; margin-bottom: 4px; }} .btn-export-pdf {{ background: #fff; color: #6c5ce7; border: 1.5px solid #6c5ce7; border-radius: 20px; padding: 7px 22px; font-size: 13px; font-weight: 600; cursor: pointer; transition: all 0.2s ease; }} .btn-export-pdf:hover {{ background: #f8f6ff; transform: translateY(-1px); }} .btn-export-pdf:active {{ transform: translateY(0); }} /* ===== PDF内容区域 ===== */ .pdf-content {{ background: transparent; }} /* ===== 头部卡片 - 紫色渐变 ===== */ .hot-title-wrap {{ background: linear-gradient(135deg, #6c5ce7, #a29bfe); border-radius: 14px; padding: 24px 24px 20px; margin-bottom: 18px; color: #fff; text-align: center; }} .hot-title-wrap h1 {{ font-size: 22px; font-weight: 800; letter-spacing: 0.5px; }} .hot-update-time {{ margin-top: 4px; font-size: 12.5px; opacity: 0.85; }} /* 统计卡片区 */ .stats-row {{ display: flex; justify-content: center; gap: 16px; margin-top: 16px; }} .stat-card {{ background: rgba(255,255,255,0.18); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-radius: 11px; padding: 11px 20px; min-width: 95px; text-align: center; }} .stat-num {{ font-size: 21px; font-weight: 800; }} .stat-label {{ font-size: 11.5px; opacity: 0.85; margin-top: 2px; }} /* ===== 表格区域 ===== */ .table-area {{ background: transparent; }} /* 卡片式表格 */ .hot-table {{ width: 100%; border-collapse: separate; border-spacing: 0 6px; }} .hot-table thead {{ display: none; }} .hot-table tbody tr {{ background: #fff; border-radius: 10px; transition: all 0.2s ease; cursor: pointer; }} .hot-table tbody tr:hover {{ transform: translateY(-1.5px); box-shadow: 0 6px 20px rgba(108,92,231,0.15); }} .hot-table td {{ padding: 13px 14px; vertical-align: middle; border: none; }} .hot-table tr td:first-child {{ border-radius: 10px 0 0 10px; }} .hot-table tr td:last-child {{ border-radius: 0 10px 10px 0; }} /* 排名序号 */ .rank-cell {{ width: 58px; text-align: center; }} /* TOP3 奖牌徽章 */ .rank-badge {{ display: inline-flex; align-items: center; justify-content: center; width: 31px; height: 31px; border-radius: 50%; font-size: 14px; font-weight: 800; position: relative; }} /* TOP1 紫红 */ .rank-badge.top1 {{ background: linear-gradient(135deg, #e056a0, #a855f7); color: #fff; box-shadow: 0 2px 8px rgba(168,85,247,0.35); }} /* TOP2 蓝紫 */ .rank-badge.top2 {{ background: linear-gradient(135deg, #6c5ce7, #74b9ff); color: #fff; box-shadow: 0 2px 8px rgba(108,92,231,0.30); }} /* TOP3 浅紫 */ .rank-badge.top3 {{ background: linear-gradient(135deg, #a29bfe, #dfe6e9); color: #6c5ce7; box-shadow: 0 2px 8px rgba(162,155,254,0.35); }} /* 4+ 序号 */ .rank-normal {{ font-size: 13px; font-weight: 700; color: #555; }} /* TOP1-3 行左侧色条 + 背景色 */ .hot-table tbody tr.row-top1 {{ background: linear-gradient(90deg, rgba(168,85,247,0.07), #fff 6%); }} .hot-table tbody tr.row-top2 {{ background: linear-gradient(90deg, rgba(108,92,231,0.07), #fff 6%); }} .hot-table tbody tr.row-top3 {{ background: linear-gradient(90deg, rgba(162,155,254,0.09), #fff 6%); }} .hot-table tbody tr.row-top1 > td:first-child {{ border-left: 3.5px solid #a855f7; }} .hot-table tbody tr.row-top2 > td:first-child {{ border-left: 3.5px solid #6c5ce7; }} .hot-table tbody tr.row-top3 > td:first-child {{ border-left: 3.5px solid #a29bfe; }} /* 标题描述 */ .info-cell {{}} .topic-title-link {{ text-decoration: none; display: block; }} .topic-title-link:hover .topic-title {{ color: #6c5ce7; }} .topic-title {{ font-size: 14.5px; font-weight: 650; color: #222; line-height: 1.45; word-break: break-all; transition: color 0.2s ease; }} .topic-desc {{ font-size: 12.5px; color: #888; margin-top: 3px; line-height: 1.4; word-break: break-all; }} /* 热度值 - 纯紫色 */ .heat-cell {{ text-align: right; white-space: nowrap; width: 110px; }} .heat-value {{ font-size: 14px; font-weight: 800; color: #6c5ce7; }} /* 标签 */ .tag {{ display: inline-block; font-size: 11px; font-weight: 600; padding: 2px 9px; border-radius: 10px; margin-right: 4px; vertical-align: middle; }} .tag-hot {{ background: rgba(231,76,60,0.08); color: #e74c3c; }} .tag-new {{ background: rgba(52,152,219,0.08); color: #3498db; }} .tag-hot-rising {{ background: rgba(230,126,34,0.1); color: #e67e22; }} .tag-descend {{ background: rgba(149,165,166,0.1); color: #7f8c8d; }} .tag-steady {{ background: rgba(39,174,96,0.1); color: #27ae60; }} /* 时间标签 */ .time-tag {{ font-size: 11.5px; color: #999; white-space: nowrap; }} /* 底部说明 */ .footer-note {{ text-align: center; font-size: 11.5px; color: #bbb; margin-top: 20px; padding: 10px 0; }} @media (max-width: 480px) {{ .page-wrap {{ padding: 10px 8px 24px; }} .hot-title-wrap {{ padding: 18px 16px 16px; }} .stats-row {{ gap: 8px; }} .stat-card {{ padding: 8px 14px; min-width: 75px; }} .stat-num {{ font-size: 18px; }} .hot-table td {{ padding: 10px 10px; }} .topic-title {{ font-size: 13.5px; }} .heat-value {{ font-size: 15px; }} }} </style> </head> <body> <div class="page-wrap"> <!-- 导出按钮(不包含在PDF内) --> <div class="export-bar"> <button class="btn-export-pdf" onclick="exportPdf()">导出 PDF</button> </div> <!-- PDF内容区域 --> <div class="pdf-content" id="pdfContent"> <!-- 头部 --> <div class="hot-title-wrap"> <h1>🔥 {page_title}</h1> <div class="hot-update-time">更新时间:{fetch_time}</div> <div class="stats-row"> <div class="stat-card"> <div class="stat-num" id="totalCount">--</div> <div class="stat-label">话题总数</div> </div> <div class="stat-card"> <div class="stat-num" id="maxHeat">--</div> <div class="stat-label">最高热度</div> </div> <div class="stat-card"> <div class="stat-num" id="avgHeat">--</div> <div class="stat-label">平均热度</div> </div> </div> </div> <!-- 表格 --> <div class="table-area"> <table class="hot-table"> <thead> <tr><th>排名</th><th>话题信息</th><th>热度值</th></tr> </thead> <tbody id="hotTableBody"></tbody> </table> </div> <div class="footer-note">数据来源:抖音 · 仅供参考</div> </div><!-- /pdf-content --> </div><!-- /page-wrap --> <script> // 行点击跳转 - 使用 location.href 避免 file:// 下 window.open 被拦截 (function() {{ function bindRowClick() {{ var rows = document.querySelectorAll('.hot-table tbody tr[data-href]'); rows.forEach(function(row) {{ row.style.cursor = 'pointer'; row.addEventListener('click', function(e) {{ if (e.target.closest('button, a, .btn-export-pdf')) return; var url = this.getAttribute('data-href'); if (url) window.location.href = url; }}); }}); }} if (document.readyState === 'loading') {{ document.addEventListener('DOMContentLoaded', bindRowClick); }} else {{ bindRowClick(); }} }})(); // 渲染热榜数据 (function() {{ var RAW = {js_data}; // 统计 var totalCount = RAW.length; var maxH = 0, sumH = 0; for (var i = 0; i < RAW.length; i++) {{ var h = parseInt(RAW[i].hotCount || RAW[i].hotValue || 0); if (h > maxH) maxH = h; sumH += h; }} var avgH = totalCount > 0 ? sumH / totalCount : 0; function fmtHot(n) {{ n = parseInt(n || 0); if (n >= 100000000) return (n / 100000000).toFixed(1) + '亿'; if (n >= 10000) return (n / 10000).toFixed(1) + 'w'; // 保留一位小数,如 1109.6w return n.toString(); }} // 更新统计 document.getElementById('totalCount').textContent = totalCount; document.getElementById('maxHeat').textContent = fmtHot(maxH); document.getElementById('avgHeat').textContent = fmtHot(Math.round(avgH)); // 保持API返回的原始排名顺序(不重新排序) // ⚠️ 数据一致性要求:必须使用API返回的原始数据,禁止修改排名、热度、链接 // RAW.sort(function(a, b) {{ return (a.index || 999) - (b.index || 999); }}); // 渲染表格 - 显示TOP{top_n} // ⚠️ 每条数据的URL必须是API返回的真实链接,禁止伪造或替换 // ⚠️ 热度值直接使用Python格式化后的值(_fmtHeat),确保与智能体表格一致 var html = ''; for (var i = 0; i < RAW.length && i < {top_n}; i++) {{ var d = RAW[i]; var rank = i + 1; var title = d.title || d.word || '--'; // 直接使用Python格式化后的热度值,不再使用fmtHot函数 var heatDisplay = d._fmtHeat || fmtHot(d.hotCount || d.hotValue || 0); var desc = d.desc || d.excerpt || d._genDesc || ''; // 链接必须使用API返回的真实URL var url = d.url || d.schemeUrl || '#'; // TOP3 样式类 var rowCls = '', badgeHtml = '', tagHtml = ''; if (rank === 1) {{ rowCls = 'row-top1'; badgeHtml = '<span class="rank-badge top1">🥇</span>'; tagHtml = '<span class="tag tag-new">新</span>'; }} else if (rank === 2) {{ rowCls = 'row-top2'; badgeHtml = '<span class="rank-badge top2">🥈</span>'; tagHtml = '<span class="tag tag-hot">热</span>'; }} else if (rank === 3) {{ rowCls = 'row-top3'; badgeHtml = '<span class="rank-badge top3">🥉</span>'; tagHtml = '<span class="tag tag-hot-rising">升</span>'; }} else {{ badgeHtml = '<span class="rank-normal">' + rank + '</span>'; }} html += '<tr class="' + rowCls + '" data-href="' + url + '">' + '<td class="rank-cell">' + badgeHtml + '</td>' + '<td class="info-cell">' + '<a class="topic-title-link" href="' + url + '" target="_blank" onclick="event.stopPropagation()"><div class="topic-title">' + title + '</div></a>' + '<div class="topic-desc">' + desc + '</div>' + '</td><td class="heat-cell">' + '<div class="heat-value">' + heatDisplay + '</div>'; if (tagHtml) {{ html += '<div style="margin-top:3px">' + tagHtml + '</div>'; }} html += '</td></tr>'; }} document.getElementById('hotTableBody').innerHTML = html; // 重新绑定行点击事件(动态插入后) var rows = document.querySelectorAll('.hot-table tbody tr[data-href]'); rows.forEach(function(row) {{ row.addEventListener('click', function(e) {{ if (e.target.closest('button, a, .btn-export-pdf')) return; var u = this.getAttribute('data-href'); if (u && u !== '#') window.location.href = u; }}); }}); }})(); // 导出PDF - 只截取 pdfContent 区域,单页自适应A4,支持链接跳转 function exportPdf() {{ var btn = document.querySelector('.btn-export-pdf'); btn.textContent = '生成中...'; btn.style.pointerEvents = 'none'; var target = document.getElementById('pdfContent'); // 收集所有链接信息 - 链接必须是API返回的真实URL var links = []; var rows = document.querySelectorAll('.hot-table tbody tr[data-href]'); rows.forEach(function(row, idx) {{ var url = row.getAttribute('data-href'); if (url && url !== '#') {{ links.push({{ url: url, top: row.offsetTop, height: row.offsetHeight, idx: idx }}); }} }}); html2canvas(target, {{ scale: 2, useCORS: true, backgroundColor: '#f0f0f5', logging: false, windowWidth: target.scrollWidth, windowHeight: target.scrollHeight }}).then(function(canvas) {{ var imgData = canvas.toDataURL('image/png'); var pdf = new jspdf.jsPDF('p', 'mm', 'a4'); var pdfW = pdf.internal.pageSize.getWidth(); var pdfH = pdf.internal.pageSize.getHeight(); var margin = 10; var contentW = pdfW - margin * 2; var contentH = pdfH - margin * 2; var imgW = contentW; var imgH = (canvas.height * imgW) / canvas.width; // 计算缩放比例 var scaleX = imgW / target.scrollWidth; var scaleY = imgH / target.scrollHeight; // 计算内容在PDF中的位置 var imgX, imgY; if (imgH > contentH) {{ imgH = contentH; imgW = (canvas.width * imgH) / canvas.height; scaleX = imgW / target.scrollWidth; scaleY = imgH / target.scrollHeight; imgX = (contentW - imgW) / 2 + margin; imgY = margin; }} else {{ imgX = margin; imgY = margin; }} // 添加图片 pdf.addImage(imgData, 'PNG', imgX, imgY, imgW, imgH); // 添加可点击链接注解(覆盖整行) // 注意:PDF阅读器对链接注解的支持不一,但这是PDF规范的标准方式 links.forEach(function(link) {{ // 转换坐标:HTML像素 -> PDF毫米 var pdfY = imgY + (link.top * scaleY); var pdfH = Math.max(link.height * scaleY, 3); // 最小高度3mm确保可点击 var pdfX = imgX; var pdfW = imgW; // 使用 link 方法添加链接注解 // 这是PDF规范的标准方式,大多数现代PDF阅读器支持 pdf.link(pdfX, pdfY, pdfW, pdfH, {{ url: link.url }}); }}); var now = new Date(); var dateStr = now.getFullYear() + String(now.getMonth()+1).padStart(2,'0') + String(now.getDate()).padStart(2,'0') + '_' + String(now.getHours()).padStart(2,'0') + String(now.getMinutes()).padStart(2,'0'); pdf.save('{page_title}_' + dateStr + '.pdf'); btn.textContent = '导出 PDF'; btn.style.pointerEvents = ''; // 提示用户PDF链接功能 console.log('PDF已生成,包含' + links.length + '个可点击链接'); }}).catch(function(err) {{ alert('PDF 生成失败:' + err.message); btn.textContent = '导出 PDF'; btn.style.pointerEvents = ''; }}); }} </script> </body> </html>''' return html def load_result_from_json(json_path): """ 从JSON文件读取热榜数据结果。 支持两种JSON格式: 1. 完整结果对象:{"fetch_time": "...", "query_type": "...", "hot_list": [...]} 2. 纯数组:[{"index": 1, "title": "...", "hotCount": "...", "url": "..."}, ...] """ with open(json_path, 'r', encoding='utf-8') as f: content = f.read().strip() data = json.loads(content) if isinstance(data, list): # 纯数组格式:包装成完整结果对象 return { "fetch_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "query_type": "实时", "hot_list": data } elif isinstance(data, dict): # 完整结果对象:确保有 hot_list if "hot_list" not in data: # 可能是 {"data": [...]} 或 {"list": [...]} 格式 hot_list = data.get("data", data.get("list", [])) return { "fetch_time": data.get("fetch_time", datetime.now().strftime("%Y-%m-%d %H:%M:%S")), "query_type": data.get("query_type", "实时"), "hot_list": hot_list } return data else: raise ValueError(f"不支持的JSON格式: {type(data)}") if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description='生成抖音热榜HTML页面') parser.add_argument('--json-file', type=str, help='从JSON文件读取热榜数据(优先使用,避免重复API调用)') parser.add_argument('--start-date', type=str, help='开始日期,格式 YYYY-MM-DD') parser.add_argument('--end-date', type=str, help='结束日期,格式 YYYY-MM-DD') parser.add_argument('--days', type=int, help='查询天数') parser.add_argument('--output', type=str, help='输出文件路径') parser.add_argument('--top', type=int, default=20, help='显示条数,默认20,可设为50') args = parser.parse_args() # 数据获取:优先从JSON文件读取,其次通过API获取 if args.json_file: if not os.path.isfile(args.json_file): print(f"❌ JSON文件不存在: {args.json_file}", file=sys.stderr) sys.exit(1) print(f"从JSON文件读取数据: {args.json_file}", file=sys.stderr) result = load_result_from_json(args.json_file) else: print("正在获取抖音热榜数据...", file=sys.stderr) result = fetch_douyin_hotspot( start_date=args.start_date, end_date=args.end_date, days=args.days ) html = generate_html(result, top_n=args.top) if args.output: output_path = args.output else: output_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "douyin_hot_trend.html") with open(output_path, 'w', encoding='utf-8') as f: f.write(html) print(f"✅ 已生成:{output_path}", file=sys.stderr) print(f"📊 共 {len(result['hot_list'])} 条热榜数据,展示TOP{args.top}", file=sys.stderr) -
hotspot_fetcher.py 6.2 KB
#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 抖音热榜数据获取脚本 功能:调用红狐数据热榜API获取抖音实时热点数据 接口:https://redfox.hk/story/api/hotSpot/getListByPlatform 参数:platform=2, source=抖音热榜-GitHub, startDate, endDate(可选) 方法:GET 认证:X-API-KEY(三级回退:环境变量 → shell配置文件 → 提示用户配置) """ import json import os import sys import re from datetime import datetime, timedelta import requests def get_api_key(): """ 获取 REDFOX_API_KEY,按三级优先级回退: 1. 从当前设备环境变量 REDFOX_API_KEY 获取 2. 从 shell 配置文件(~/.bashrc / ~/.bash_profile / ~/.zshrc)中读取 3. 提示用户配置 Returns: str: API Key 字符串 Raises: SystemExit: 未能获取到有效的 API Key """ # 第一级:从环境变量获取 api_key = os.getenv("REDFOX_API_KEY") if api_key and api_key.strip(): return api_key.strip() # 第二级:从 shell 配置文件读取 home = os.path.expanduser("~") shell_configs = [ os.path.join(home, ".bashrc"), os.path.join(home, ".bash_profile"), os.path.join(home, ".zshrc"), ] for config_path in shell_configs: if os.path.isfile(config_path): try: with open(config_path, "r", encoding="utf-8", errors="ignore") as f: content = f.read() match = re.search( r'export\s+REDFOX_API_KEY\s*=\s*["\']?([a-zA-Z0-9_]+)["\']?', content ) if match: api_key = match.group(1).strip() if api_key: return api_key except Exception: continue # 第三级:提示用户配置 error_msg = { "error": "缺少 REDFOX_API_KEY 配置", "hint": "请设置环境变量 REDFOX_API_KEY=ak_xxxxxxxx,或将其写入 shell 配置文件(~/.bashrc / ~/.bash_profile / ~/.zshrc)", "guide": "访问 https://redfox.hk/login 注册账号,在个人中心获取 API Key" } print(json.dumps(error_msg, ensure_ascii=False)) sys.exit(1) def fetch_douyin_hotspot(start_date=None, end_date=None, days=None): """ 获取抖音热榜数据 使用原生 requests 发起请求,X-API-KEY 通过三级回退获取 Args: start_date: 开始日期,格式 YYYY-MM-DD end_date: 结束日期,格式 YYYY-MM-DD days: 查询天数,如7表示近7天,30表示近30天 Returns: None (结果直接打印到标准输出) """ # 获取 API Key(三级回退) credential = get_api_key() # 构建请求URL url = "https://redfox.hk/story/api/hotSpot/getListByPlatform" # 构建请求参数 params = { "platform": 2, "source": "抖音热榜-GitHub" } # 处理日期参数 query_type = "实时" if days: today = datetime.now().date() end_date_obj = today start_date_obj = today - timedelta(days=days) params["startDate"] = start_date_obj.strftime("%Y-%m-%d") params["endDate"] = end_date_obj.strftime("%Y-%m-%d") query_type = f"近{days}天" if start_date and end_date: params["startDate"] = start_date params["endDate"] = end_date query_type = f"{start_date} 至 {end_date}" # 构建请求头 headers = { "X-API-KEY": credential, "Accept": "application/json, text/plain, */*", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } try: response = requests.get(url, params=params, headers=headers, timeout=30) if response.status_code >= 400: raise Exception(f"HTTP请求失败: {response.status_code}, {response.text}") api_response = response.json() # 处理不同的响应格式 if isinstance(api_response, dict): if "data" in api_response: data = api_response["data"] elif "list" in api_response: data = api_response["list"] else: data = [] elif isinstance(api_response, list): data = api_response else: data = [] # 提取并格式化热榜数据 if isinstance(data, list): now = datetime.now() fetch_time = now.strftime("%Y-%m-%d %H:00") result = { "fetch_time": fetch_time, "query_type": query_type, "start_date": start_date, "end_date": end_date, "hot_list": [] } for item in data: # 处理标题:去除所有空格(半角空格、全角空格、制表符、换行符等) title = item.get("title", "") if title: title = ''.join(title.split()) result["hot_list"].append({ "index": item.get("index"), "title": title, "hotCount": item.get("hotCount", ""), "url": item.get("url", "") }) print(json.dumps(result, ensure_ascii=False, indent=2)) else: print(json.dumps([], ensure_ascii=False)) except requests.exceptions.RequestException as e: error_msg = {"error": f"请求失败: {str(e)}"} print(json.dumps(error_msg, ensure_ascii=False)) sys.exit(1) except Exception as e: error_msg = {"error": f"错误: {str(e)}"} print(json.dumps(error_msg, ensure_ascii=False)) sys.exit(1) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description='获取抖音热榜数据') parser.add_argument('--start-date', type=str, help='开始日期,格式 YYYY-MM-DD') parser.add_argument('--end-date', type=str, help='结束日期,格式 YYYY-MM-DD') parser.add_argument('--days', type=int, help='查询天数,如7表示近7天,30表示近30天') args = parser.parse_args() fetch_douyin_hotspot( start_date=args.start_date, end_date=args.end_date, days=args.days )
-
-
README.en.md 6.1 KB
# Douyin Hot Trend Tracker / douyin-hot-trend --- ## Introduction A smart hot trend tool that tracks Douyin trending topics in real time, uncovers viral content patterns, and helps creators and operators catch hot topics and find content ideas efficiently. **Core Value** - Automatically updates the Douyin TOP 50 chart every hour, with heat scores and direct links at a glance - Covers up to 30 days of historical charts so you can trace past trend shifts anytime - Automatically generates topic opportunity analysis, title pattern breakdowns, and trend forecasts from a creator's perspective - Supports side-by-side comparison of any two time points, clearly marking newly-entered and dropped topics - Supports hourly or daily scheduled delivery — no manual triggering needed **Who It's For** - 🎬 **Short-video Creators** — Quickly lock in daily hot topics and shorten your ideation time - 📣 **MCN Operations Teams** — Monitor platform trends centrally and guide creator content strategies efficiently - 🏷️ **Brand Marketing Managers** — Identify leverage-worthy topics and respond to hot trends faster - 📚 **Operations Beginners** — Learn viral title patterns and quickly build content intuition --- ## Features ### Core Functions - **Real-Time Chart Query**: Fetch the current Douyin TOP 50 trending topics with rankings, heat scores, titles, and clickable links — refreshed every 60 minutes - **Historical Chart Lookup**: Query up to the past 7 days or 30 days of trending data, with support for specifying an exact date - **Chart Comparison**: Compare rankings and heat score changes between any two time points, with new entrants and dropped topics automatically flagged - **Creator Insights Report**: After displaying the chart, automatically outputs viral topic opportunities, title pattern analysis, trend forecasts, and actionable recommendations - **Visual Report Export**: One-click generation of a minimal-purple-style HTML page with PDF export support and clickable links for every topic - **Scheduled Subscription Push**: Set up hourly or daily automated delivery to stay on top of trending topics without manual effort --- ## 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`). - Register an account at [RedFoxHub](https://redfox.hk?source=github) to obtain your `REDFOX_API_KEY`. - Configure the device environment variable `REDFOX_API_KEY` before using this skill. - Before providing a key, confirm its source, scope, expiration, and whether it supports reset/revocation. - Never hardcode or expose the key in plaintext in code, prompts, logs, or output files. --- ## Usage Guide Just describe your need in plain language — no commands to memorize. ### Quick Reference | Intent | Example Phrase | Result | | ----------------------- | ------------------------------------------------ | ------------------------------------------------------------------------------- | | Check real-time chart | "Douyin trending" / "Today's hot list" | Shows current TOP 20 with heat scores and links, plus a creator insights report | | Check yesterday's chart | "Yesterday's hot list" | Retrieves all-day trending data from yesterday | | View historical chart | "Hot list from the past 7 days" / "Past 30 days" | Traces trending topics over the selected time range | | View a specific date | "Hot list from May 15" | Retrieves the chart for that specific date | | Load the full chart | "Load more" / "Continue loading" | Expands from TOP 20 to the full TOP 50 | | Compare chart changes | "Compare today's and yesterday's hot list" | Outputs differences between the two days with flagged new entrants and dropouts | | Subscribe to updates | "Subscribe to daily hot list push" | Sets up scheduled automatic delivery every day | | Cancel subscription | "Cancel subscription" | Stops scheduled delivery | ### Sample Output After querying "Today's hot list", you will receive: 1. **Trending Table**: Rank, topic title, heat score, and direct links (TOP 20; expandable to 50) 2. **Creator Insights Report**: - 🔥 Viral Topic Opportunities (transferable topics and content angles) - 🎯 Title Pattern Breakdown (emotional hooks, sentence structures) - 📈 Trend Forecast (which topics are rising or falling) - 💡 Action Recommendations (executable content strategy suggestions) 3. **Visual Report**: Auto-generated HTML page with PDF export support --- ## Use Cases | Scenario | Role | Example Query | Benefit | | ------------------------ | ----------------------- | ----------------------------------------------- | ------------------------------------------------------------------------------- | | Daily content ideation | Short-video Creator | "Today's hot list" | Quickly identify hot directions and get transferable topics with title formulas | | Trend monitoring | MCN Operations | "Past 7 days hot list" | Track a week's trend shifts and inform creator content strategy | | Brand hot-topic leverage | Brand Marketing Manager | "Compare this week's chart changes" | Spot sustained topics and plan brand content in advance | | Operations learning | Short-video Beginner | "Today's hot list — analyze the title patterns" | Learn viral sentence structures and rapidly build content intuition | --- -
README.md 4.8 KB
# 抖音热榜神器 / douyin-hot-trend --- ## 简介 实时追踪抖音热点、挖掘爆款规律,帮助内容创作者和运营者高效蹭热点、找选题的智能热榜工具。 **核心价值** - 每小时自动更新抖音 TOP 50 榜单,热度值与跳转链接一键可见 - 覆盖近 7 天、近 30 天历史热榜,随时回溯过往热点演变 - 从创作者视角自动生成选题机会、标题套路与趋势预判 - 支持任意两个时间点热榜对比,清晰标注新进榜与掉榜话题 - 支持每小时或每日定时推送,无需手动触发 **适用对象** - 🎬 **短视频创作者** — 每天快速锁定热点方向,缩短选题时间 - 📣 **MCN 机构运营** — 统一监控平台趋势,高效指导达人内容策略 - 🏷️ **品牌营销人员** — 发现可借势话题,提升热点响应速度 - 📚 **运营新手** — 学习爆款标题套路,快速建立内容感知 --- ## 功能特性 ### 核心功能 - **实时热榜查询**:获取抖音当前 TOP 50 热榜,包含排名、热度值、话题标题和跳转链接,每 60 分钟刷新 - **历史热榜回溯**:支持查询近 7 天或近 30 天历史数据,可按日期指定查看特定某天 - **热榜对比**:对比任意两个时间点的热榜排名与热度变化,自动标注新进榜与掉榜话题 - **创作者洞察报告**:热榜展示后自动输出爆款选题机会、标题套路拆解、趋势预判与行动建议 - **可视化报告导出**:一键生成紫色极简风格 HTML 页面,支持导出 PDF,每条话题可点击跳转 - **定时订阅推送**:支持每小时或每日定时推送,自动追踪热点变化 --- ## 密钥获取与安全说明 - 本技能需要使用环境变量:`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` 后使用本技能。 - 在提供密钥前,请先确认密钥来源、可用范围、有效期及是否支持重置/撤销。 - 禁止在代码、提示词、日志或输出文件中硬编码/明文暴露密钥。 --- ## 使用指南 直接用自然语言描述需求,无需记忆命令。 ### 常用说法速查 | 意图 | 示例话术 | 效果 | | ------------ | ---------------------- | ----------------------------------------------------- | | 查看实时热榜 | 抖音热榜 / 今日热榜 | 展示当前 TOP 20,含热度值与话题链接,附创作者洞察报告 | | 查看昨日热榜 | 昨日热榜 | 查询昨天全天热榜数据 | | 查看历史热榜 | 近7天热榜 / 近30天热榜 | 按时间范围回溯历史热点 | | 查看指定日期 | 5月15日热榜 | 查询特定日期的榜单数据 | | 加载完整榜单 | 继续加载 / 加载更多 | 从 TOP 20 扩展至完整 TOP 50 | | 对比热榜变化 | 对比昨天和今天的热榜 | 输出两日热榜差异,标注新进榜与掉榜话题 | | 订阅推送 | 订阅每日热榜推送 | 设置定时自动推送,每日获取最新热榜 | | 取消订阅 | 取消订阅 | 停止定时推送 | ### 输出示例 查询「今日热榜」后,你将收到: 1. **热榜表格**:序号、话题标题、热度值、跳转链接(TOP 20,可继续加载至 50) 2. **创作者洞察报告**: - 🔥 爆款选题机会(可迁移话题与创作方向) - 🎯 标题套路拆解(情绪词、句式结构) - 📈 趋势预判(哪些话题正在上升/下降) - 💡 行动建议(可执行的内容策略) 3. **可视化报告**:自动生成 HTML 页面,支持导出 PDF --- ## 使用场景 | 场景 | 角色 | 示例问法 | 收益 | | ------------ | ------------ | ------------------------------ | -------------------------------------------- | | 每日选题灵感 | 短视频创作者 | 「今日热榜」 | 快速锁定热点方向,获取可迁移选题与标题公式 | | 热点趋势监控 | MCN 运营人员 | 「近7天热榜」 | 掌握一周热点演变规律,为达人提供内容策略参考 | | 热点借势营销 | 品牌营销经理 | 「对比本周热榜变化」 | 发现持续发酵话题,提前布局品牌借势内容 | | 运营学习研究 | 短视频新手 | 「今日热榜,帮我分析标题套路」 | 学习爆款句式结构,快速建立内容感知 | --- -
SKILL.md 11.9 KB
--- name: douyin-hot-trend description: 专注于获取抖音最新的热榜数据,每小时更新,包含热点事件、热度值和跳转链接;支持查询近7天、近30天历史热榜,并支持订阅定时推送。 --- # 抖音热榜 ## 简介 抖音热榜是一款实时追踪抖音平台热点趋势的数据工具,对接 [红狐Hub](https://redfox.hk/?source=github) 数据 API,每小时更新热榜内容,并提供创作者视角的深度分析。 通过简单的自然语言指令,你可以: - 📊 **实时热榜查询**:每 60 分钟抓取抖音 TOP 50 榜单,同步热度值与跳转链接 - 📅 **历史热榜回溯**:覆盖近 7 天、近 30 天历史数据,支持按日期与关键词检索 - 🔀 **热榜数据对比**:对比任意两个时间点(如昨天 vs 今天)的热榜变化 - 💡 **深度洞察分析**:从创作者视角提供选题机会、标题套路与趋势预判 - 🔔 **个性化订阅**:支持每小时或每日定时推送热榜数据 适用于内容创作者、短视频运营、MCN 机构、品牌营销人员等需要追踪抖音热点、寻找创作灵感、制定内容策略的场景。 **技术基础**:Python 3.x + `requests` 库,通过 红狐Hub APIKey获取数据。 --- ## 功能特性 ### 🎯 核心功能 - **📊 实时热榜**:获取抖音当前 TOP 50 热榜,每小时刷新,展示排名、热度值、话题标题和跳转链接 - **📅 历史回溯**:支持查询近 7 天或近 30 天历史热榜,最长覆盖 30 天 - **💡 创作者洞察**:自动生成选题机会分析、标题套路拆解、趋势预判与行动建议 - **📄 可视化报告**:一键生成紫色极简风格 HTML 页面,支持导出 PDF,每条记录可点击跳转 - **🔔 订阅推送**:支持每小时或每日定时推送,自动追踪热点变化 ### ✨ 特色亮点 - **⚡ 自然语言交互**:输入「今日热榜」「近7天热榜」等即可查询,无需记忆命令参数 - **🔒 三级鉴权回退**:API Key 优先从环境变量读取,自动回退到 Shell 配置文件 - **✅ 数据一致性**:表格、洞察、HTML、PDF 全链路数据一致,不做加工或美化 - **🎬 创作者视角**:每条洞察都回答「怎么用」,给出可执行的行动建议 --- ## 一键安装 ### 前置条件 - 已安装 Python 3.x 及 `requests` 库 - 已注册 [红狐Hub官网](https://redfox.hk/login?source=github) 账号并获取 API Key(格式 `ak_xxxxxxxx`) - 新注册用户将获赠免费积分,可立即开始使用 ### 安装方式 #### 方式一:WorkBuddy(龙虾)技能安装(推荐) 1. 将 `douyin-hot-trend` 技能文件夹复制到 WorkBuddy 的 skills 目录下 2. 在 WorkBuddy 对话中直接说「抖音热榜」或「今日热榜」,Agent 将自动加载本技能 3. 配置 API Key(见下方「环境变量配置」) 4. 安装 Python 依赖: ```bash pip install requests ``` #### 方式二:Cursor / 其他 Agent 环境手动安装 1. 将技能文件夹放置到对应环境的 skills 目录 2. 确保 Agent 可读取 `SKILL.md` 与 `references/core_workflow.md` 3. 配置 `REDFOX_API_KEY` 环境变量 4. 执行 `pip install requests` ### 环境变量配置 | 变量名 | 必填 | 说明 | |------|------|------| | `REDFOX_API_KEY` | 是 | 红狐Hub API 访问密钥,格式 `ak_xxxxxxxx` | **配置方式**(任选其一): ```bash # 方式一:直接设置环境变量(推荐) export REDFOX_API_KEY=ak_xxxxxxxx # 方式二:写入 Shell 配置文件(~/.bashrc / ~/.bash_profile / ~/.zshrc) echo 'export REDFOX_API_KEY=ak_xxxxxxxx' >> ~/.bashrc source ~/.bashrc ``` 若未配置环境变量,技能将自动从 Shell 配置文件读取;若仍未获取到,会在运行时提示配置。 **在 WorkBuddy 中配置 Key**:可在系统环境变量中设置 `REDFOX_API_KEY`,或在 Shell 配置文件中写入后重启 WorkBuddy,无需在每次对话中手动传入。 --- ## 使用指南 ### 基础使用 #### 1. 查看实时热榜 告诉助手你想查看当前抖音热点: > **用户**:抖音热榜 > **助手**:为您展示抖音实时热榜 TOP 20(含排名、热度值、话题链接),并附创作者洞察报告。 #### 2. 查看历史热榜 查询指定时间范围的历史数据: > **用户**:近7天热榜 > **助手**:为您展示近 7 天抖音历史热榜,支持按日期回溯热点演变。 > **用户**:4月15日热榜 > **助手**:为您查询 4 月 15 日当天的热榜数据。 #### 3. 加载完整榜单 默认展示 TOP 20,可继续加载至 TOP 50: > **用户**:继续加载 > **助手**:为您展示 TOP 21–50,并生成包含完整 TOP 50 的 HTML 报告。 ### 高级使用 #### 1. 创作者洞察 热榜展示后自动输出深度分析: > **用户**:今日热榜 > **助手**:(展示表格后)输出爆款选题机会、标题套路破解、趋势预判与行动建议。 #### 2. 热榜对比 对比两个时间点的热榜变化: > **用户**:对比昨天和今天的热榜 > **助手**:为您对比两日热榜排名与热度变化,标注新进榜与掉榜话题。 #### 3. 订阅推送 设置定时自动推送: > **用户**:订阅每日热榜推送 > **助手**:已设置每日推送,将在指定时间自动推送 TOP 50 完整热榜数据。 > **用户**:取消订阅 > **助手**:已取消定时推送。 #### 4. 生成报告 每次查询自动生成可视化报告: > **用户**:今日热榜 > **助手**:(查询完成后)已生成 HTML 页面与 PDF 文件,数据与表格展示完全一致,支持点击跳转。 ### 常用指令速查 | 指令 | 功能 | |------|------| | 抖音热榜 / 今日热榜 | 查询实时热榜 TOP 20 | | 昨日热榜 | 查询昨日热榜 | | 近7天热榜 | 查询近 7 天历史热榜 | | 近30天热榜 | 查询近 30 天历史热榜 | | X月X日热榜 | 查询指定日期热榜 | | 继续加载 / 加载更多 | 加载 TOP 21–50 完整榜单 | | 订阅每日/每小时推送 | 设置定时推送 | | 取消订阅 | 停止定时推送 | --- ## 使用场景 ### 场景一:内容创作者找选题 **角色**:抖音短视频创作者 **需求**:每天快速了解平台热点,找到适合自己赛道的创作方向 **使用方式**: 1. 每天早晨说「今日热榜」,获取最新热点 2. 查看创作者洞察报告,获取选题建议和标题公式 3. 直接套用可迁移选题,快速产出内容 **预期收益**:缩短选题时间,提高内容命中率 --- ### 场景二:MCN 机构运营管理 **角色**:MCN 运营人员 **需求**:监控平台热点趋势,为旗下达人提供选题指导和内容策略 **使用方式**: 1. 订阅每日热榜推送,自动获取最新热点 2. 查看历史热榜,分析热点演变规律 3. 将洞察报告分享给达人团队,指导内容创作 **预期收益**:提升团队内容策略的时效性和精准度 --- ### 场景三:品牌营销热点借势 **角色**:品牌营销经理 **需求**:及时发现可借势的热点话题,制定蹭热点营销方案 **使用方式**: 1. 关注每日热榜,筛选与品牌调性匹配的热点 2. 分析趋势预判,提前布局内容 3. 导出 HTML/PDF 报告,用于团队沟通和方案汇报 **预期收益**:提升品牌热点的响应速度和借势效果 --- ### 场景四:短视频运营学习研究 **角色**:短视频运营新手 **需求**:学习爆款内容的创作规律,提升运营能力 **使用方式**: 1. 定期查看热榜和创作者洞察 2. 学习标题套路和情绪触发词 3. 模仿可迁移选题进行练习 **预期收益**:快速建立内容 sense,掌握爆款创作方法论 --- ## 项目架构 ### 目录结构 ``` douyin-hot-trend/ ├── SKILL.md # 技能说明文档(当前文件) ├── references/ │ └── core_workflow.md # Agent 核心工作流指令 ├── scripts/ │ ├── hotspot_fetcher.py # 热榜数据获取脚本 │ └── gen_douyin_hot_html.py # HTML 可视化报告生成脚本 └── assets/ └── douyin_hot_trend_template.html # HTML 页面模板 ``` ### 核心模块说明 | 模块 | 文件 | 职责 | |------|------|------| | 数据获取 | `hotspot_fetcher.py` | 调用 红狐Hub API 获取抖音热榜 JSON,支持实时与历史查询 | | 报告生成 | `gen_douyin_hot_html.py` | 将热榜数据渲染为紫色极简风格 HTML,支持导出 PDF | | 页面模板 | `douyin_hot_trend_template.html` | 独立 HTML 模板,支持占位符快速替换生成 | ### 技术栈 | 类别 | 说明 | |------|------| | 运行环境 | Python 3.x | | HTTP 请求 | 原生 `requests` 库 | | 认证方式 | `X-API-KEY` 请求头,三级回退(环境变量 → Shell 配置 → 提示配置) | | 数据来源 | [红狐Hub API](https://redfox.hk?source=github) | | 部署平台 | WorkBuddy / Cursor 等 Agent 环境 | ## 常见问答 ### 安装相关问题 **Q1: 运行时提示「缺少 REDFOX_API_KEY 配置」怎么办?** A: 请按以下步骤排查: 1. 确认已注册 红狐Hub 账号并在个人中心获取 API Key 2. 设置环境变量:`export REDFOX_API_KEY=ak_xxxxxxxx` 3. 或写入 Shell 配置文件后执行 `source ~/.bashrc` 使其生效 4. 确认 API Key 格式正确,以 `ak_` 开头 **Q2: 需要安装哪些 Python 依赖?** A: 仅需 `requests` 库:`pip install requests` **Q3: 如何在 WorkBuddy(龙虾)中启用本技能?** A: 将技能文件夹放入 WorkBuddy 的 skills 目录,配置好 `REDFOX_API_KEY` 后,在对话中说「抖音热榜」即可触发。Agent 将按 `references/core_workflow.md` 执行完整工作流。 --- ### 使用相关问题 **Q4: 热榜数据多久更新一次?** A: 每小时更新一次。每次查询都会调用 API 获取最新数据,不依赖本地缓存。 **Q5: 可以查询多久之前的历史数据?** A: 最长支持查询近 30 天的历史热榜。超过 30 天的数据暂不支持。 --- ### 故障排除 **Q6: API 调用失败怎么办?** A: 请按以下顺序排查: 1. 检查网络连接,确认可以访问 `https://redfox.hk?source=github` 2. 确认 API Key 未过期,账户积分是否充足 3. 检查环境变量:`echo $REDFOX_API_KEY` 4. 稍后重试,API 服务可能存在临时波动 **Q7: 订阅推送没有收到怎么办?** A: 确认订阅已成功设置。如需重新设置,说「取消订阅」后重新订阅。如仍有问题,检查WorkBuddy等系统的自动化任务是否正常运行。 **Q8: HTML 报告预览不成功或显示空白怎么办?** A: 请按以下方式处理: 1. 确认 HTML 文件已成功生成(脚本会输出 `✅ 已生成` 提示) 2. 直接双击打开交付的 HTML 文件,用 Chrome/Edge 浏览器查看,不依赖WorkBuddy等系统内置预览 3. 若文件已交付但内置预览空白,属于已知限制——Windows 中文用户名路径可能导致预览组件兼容性问题,直接用浏览器打开即可正常显示 --- ### 安全与许可 **Q9: API Key 如何安全存储?** A: 建议通过环境变量或 Shell 配置文件存储,不要将 Key 写入代码仓库或公开分享。本技能支持三级鉴权回退,优先读取环境变量,避免在对话中明文传递。 **Q10: 数据来源与使用许可?** A: 热榜数据来自 [红狐Hub](https://redfox.hk?source=github) 官方 API,使用时须遵守 红狐Hub 平台服务条款及抖音平台相关规定。本技能仅作数据展示与分析辅助,不保证数据的商业用途合规性。 --- ### 获取帮助 如有其他问题,可通过以下方式获取帮助: - 📖 查阅 Agent 执行参考:`references/core_workflow.md` - 🌐 红狐Hub 官网:[https://redfox.hk?source=github](https://redfox.hk/?source=github) - 📧 联系 红狐Hub 平台客服获取 API 相关问题支持 --- **Agent 执行参考**:完整的操作步骤、输出格式、数据规则等执行层指令,请查阅 `references/core_workflow.md`。
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.