Claude Skill

x-top-account

X(Twitter)每日最具影响力账号榜单追踪分析工具;每日早上9:00更新前一天榜单,最多回溯7天;支持性别(男/女/全部)与32个行业分类筛选、分页翻页、HTML可视化报告导出与定时订阅推送;当用户需要查询X/Twitter账号排名、热门账号榜、分行业/分性别榜单、下载榜单报告或订阅推送时使用。触发词:X榜单、Twitter榜单、推特账号排名、X热门账号、Twitter影响力榜、推特大V排行。

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_x-top-account-5e7b435.zip · 29 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/x-top-account
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

X (Twitter) 热门账号榜 / x-top-account

中文 | English


简介

帮你快速发现 X (Twitter) 平台最具影响力的账号,掌握全球头部创作者格局。

核心价值 基于每日 X 平台 TOP200 影响力账号的粉丝、涨幅、跨平台数据,帮你解决对标账号、海外投放、竞品监控、行业洞察四大核心问题。

适用对象

  • 🌏 出海内容创作者 — 了解同赛道头部账号表现,寻找对标和学习对象
  • 🏢 品牌方/海外投放 — 高效筛选优质达人,评估跨平台合作价值
  • 📦 MCN 机构/跨境运营 — 掌握竞品动态,制定运营策略
  • 📊 行业分析师 — 获取数据洞察,生成分析报告

功能特性

核心功能

  • 排名查询:查询 X 平台每日影响力账号榜,每页 20 条、共 10 页 200 条,支持翻页浏览
  • 筛选过滤:支持性别(全部/男/女)与 32 个行业分类精准查询,支持模糊词匹配(如"宠物"自动映射萌宠动物)
  • 影响力评分:结合粉丝数、互动量、曝光数等加权综合评估,满分 100 分
  • HTML 报告生成:生成 X 平台风格的可视化 HTML 文件,账号名可点击跳转 X 主页,支持一键导出 PDF / 高清图片
  • 订阅推送:支持设置每日定时自动推送,也可按性别 / 行业组合订阅

密钥获取与安全说明

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

使用指南

直接用自然语言描述你的需求,无需记忆任何命令格式。

常用说法速查

意图 示例话术 效果
查最新榜 "给我最新的 Twitter 全品类日榜" 返回最新日期第 1 页 20 条
查行业榜 "宠物类 Twitter 账号排行怎么样?" 返回萌宠动物行业最新榜单
查性别榜 "看看美妆类女博主的 X 榜单" 返回时尚美妆 + 女性筛选榜单
指定日期 "给我 2026 年 9 月 20 日的 Twitter 榜单" 返回指定日期榜单
翻页 "继续看第 2 页" 返回第 2 页 20 条
下载报告 "帮我生成这次榜单的 HTML 报告" 生成可视化 HTML 文件并交付
订阅推送 "我想每天收到宠物类 X 榜单更新" 创建定时自动推送任务

输出示例

📈 X (Twitter) 热门账号榜 · 全部行业 · 全部

数据日期:2026-09-21(第 1/10 页) 共 200 个账号上榜(本页展示 20 条)

💡 榜单说明:每日早上 9:00 更新前一天榜单,与实时数据存在差异

📐 影响力评分:结合粉丝数、互动量、曝光数等加权综合评估,满分 100

排名 账号名 账号简介 国家/地区 主行业 影响力评分 日涨幅 X粉丝数 其他平台粉丝数 专题标签
🥇 1 账号名(可点击) 简介 美国 Tech & Software 99/100 +1.25% 2.2亿+ — 标签
🥈 2 账号名(可点击) 简介 美国 Entertainment & Culture 97/100 +0.88% 3,100w+ YouTube 4亿+ —
… … … … … … … … … …

⚡ 更多操作 本次榜单完整共 200 条数据,是否需要继续查看第 2 页?

📬 订阅服务 1️⃣ 是否需要订阅每日 X(Twitter) 账号最新排名? 2️⃣ 支持您按照性别(全部/男/女)与 32 个行业分类筛选项订阅


使用场景

场景 角色 示例问法 收益
寻找赛道标杆账号 出海创作者 / 个体运营 "科技类 Twitter 账号哪些做得好?" 快速找到行业头部,明确内容方向
评估达人合作候选人 品牌方 / 海外投放 "美妆类女博主 TOP20 有哪些表现亮眼?" 批量筛选,提升投放决策效率
监控竞品赛道动态 MCN / 跨境运营团队 "宠物榜第 2 页有哪些新面孔?" 实时掌握竞争格局,快速响应市场变化
生成行业分析报告 行业分析师 / 咨询顾问 "帮我生成金融投资行业榜单的 HTML 报告" 一键生成可视化 HTML,方便汇报分享
定期追踪账号排名变化 运营团队 "我想每天收到科技类 X 榜单更新" 订阅推送,自动化榜单情报获取

重要数据说明

榜单更新时间与数据回溯

规则 说明
更新时间 每日早上 9:00 更新昨日榜单
回溯范围 过去 7 天
空数据 目标日期无数据时,自动回退最近可用日期

支持筛选项

  • 性别(3 项):全部、男、女
  • 行业分类(32 类):全部行业、商业创业、汽车出行、设计创意、航空领域、电商零售、教育培训、工程运营、娱乐文化、环境能源、家庭育儿、时尚美妆、金融投资、美食饮品、游戏电竞、健康医疗、牧场马术、宗教信仰、科学学术、体育健身、科技软件、旅行户外、视觉艺术、健康生活、居家手工、人力职场、公益平权、法律法务、市场营销、音乐领域、萌宠动物、政治新闻

Skill manifest

X (Twitter) 热门账号榜

1. 简介

X (Twitter) 每日最具影响力账号榜单追踪分析工具 -- 基于红狐数据 API,提供 X 平台全行业 / 分行业 / 分性别的每日影响力账号榜单查询,支持排名查询、筛选过滤、分页翻页、HTML 可视化报告下载与定时订阅推送。

适用对象:出海内容创作者、品牌方 / 海外投放人员、MCN 机构 / 跨境运营团队、行业分析师 / 咨询从业者。


2. 功能特性

核心功能:

  • 排名查询 -- 查每日 TOP 账号榜(每页 20 条,共 10 页 200 条)
  • 筛选过滤 -- 按性别与 32 个行业分类精准筛选,支持自然语言模糊匹配
  • 分页翻页 -- 支持指定页码查询,对话内逐页浏览
  • 报告下载 -- 生成 X 平台风格 HTML 报告,支持一键导出 PDF / 高清图片
  • 定时订阅 -- 设置每日定时推送,支持按性别 / 行业组合订阅

特色亮点:

  • 每日早上 9:00 更新前一天榜单,最多回溯 7 天
  • 影响力评分:结合粉丝数、互动量、曝光数等加权综合评估,满分 100
  • 行业模糊匹配:支持自然语言输入(如 "宠物" 自动映射到 "萌宠动物")
  • 多维数据:国家/地区、主行业、日涨幅、X 粉丝数、其他平台粉丝数、专题标签一览无余

3. 一键安装

鉴权

获取 API Key

请前往 红狐hub 获取API KEY

配置 API Key

方案1: 以OpenClaw为例,将REDFOX_API_KEY添加到~/.openclaw/openclaw.json中

{ "env": { "REDFOX_API_KEY": "ak_xxxx..." } }

方案2: 终端配置:export REDFOX_API_KEY="ak_xxxx..."

export REDFOX_API_KEY="ak_xxxx..."

依赖安装

无需安装第三方依赖,使用 Python 标准库即可运行。


4. 使用指南

基础使用

查询榜单数据(默认第 1 页 20 条)并生成 HTML 报告:

python scripts/fetch_rank.py --query "用户原始问题" --html

脚本会自动解析:

  • 日期:未明确则取最新可用日期(每日 9:00 更新,9 点后为昨日,9 点前为前日)
  • 性别:识别 男/女(如 "女博主" → female),未明确则 all
  • 行业:模糊匹配 32 个行业(如 "宠物" → "萌宠动物"),接口 category 传行业中文名,未明确则 all;skill 内部不暴露英文分类值
  • 页码:识别 "第2页" 等表达,未明确则第 1 页

翻页查询:

python scripts/fetch_rank.py --query "用户原始问题" --page 2 --html

显式指定筛选条件(优先级高于 --query 解析结果):

python scripts/fetch_rank.py --date 2026-09-20 --gender female --category "萌宠动物" --html

重要:HTML 报告展示的数据条数必须与对话中展示的数量保持一致(每页 20 条)。使用 deliver_attachments 交付 HTML 文件。

高级使用

更新时间与回溯范围(必须输出给用户):

  • 榜单每日早上 9:00 更新前一天数据
  • 最多回溯过去 7 天

时间边界处理(必须严格遵守):

  • 查询当日及未来日期:回复「非常抱歉🙏,我们最新的是昨日的数据,将为您提供最接近您需求的昨日热榜。」
  • 查询时间早于回溯日期:回复「非常抱歉🙏,目前榜单最多支持回溯「过去7天」,我将为您查询最接近您需求的时间范围~」
  • 目标日期接口返回空数据:脚本自动回退到最近可用日期并输出 [WARN] 提示,需转述给用户

订阅服务:

用户确认订阅后,使用 automation_update 工具创建自动化任务:

  • 每日订阅:FREQ=DAILY;BYHOUR=9;BYMINUTE=30(数据 9:00 更新后推送)

automation prompt 示例:查询X(Twitter)最新热门账号榜(行业:全部行业,性别:全部),生成报告并推送给用户

订阅询问时必须罗列全部筛选项(见「输出格式」订阅服务模板):

  • 性别:全部(all) / 男(male) / 女(female)
  • 行业分类:32 个行业中文名全量罗列,完整枚举见 references/category_map.md

常用指令速查

用户意图 典型触发词 对应操作
排名查询 X榜单、Twitter日榜、推特热门账号、影响力排行 调用脚本查询并格式化输出
筛选查询 宠物类/科技类/女博主...Twitter排名 调用脚本并按行业/性别筛选
翻页 第2页、下一页、继续看 加 --page 参数重新查询
报告下载 下载报告、导出榜单、生成报告 运行脚本加 --html 生成并交付

输出格式

Markdown 表格模板:

📈 X (Twitter) 热门账号榜 · {category_label} · {gender_label}
数据日期:{rankDate}(第 {pageNum}/{pages} 页)
共 {total} 个账号上榜(本页展示 20 条)

💡 榜单说明:每日早上 9:00 更新前一天榜单,与实时数据存在差异
📐 影响力评分:结合粉丝数、互动量、曝光数等加权综合评估,满分 100

| 排名 | 账号名 | 账号简介 | 国家/地区 | 主行业 | 影响力评分 | 日涨幅 | X粉丝数 | 其他平台粉丝数 | 专题标签 |
|:---:|--------|--------|:---:|--------|:---:|:---:|:---:|--------|--------|
| 🥇 1 | [Elon Musk](profile_url)<br>*Tech Entrepreneur and CEO* | biography 简介(前 60 字) | 美国 | Tech & Software | 99/100 | +1.25% | 2.2亿+ | — | 账号标签 |
| 🥈 2 | [MrBeast](profile_url)<br>*Creator & Philanthropist* | biography 简介(前 60 字) | 美国 | Entertainment & Culture | 97/100 | +0.88% | 3,100w+ | YouTube 4亿+ | — |
| 🥉 3 | [iJustine](profile_url)<br>*Tech Vlogger* | biography 简介(前 60 字) | 美国 | Tech & Software | 93/100 | +0.69% | 180w+ | YouTube 7,100w+ / TikTok 1,600w+ | Women in Tech / STEM |

字段展示规则:

  • 账号名:Markdown 链接 [fullName](profileUrl) + <br> + 头衔(title,斜体),头衔不换列、不省略;1-3 名加 🥇🥈🥉
  • 账号简介:仅 biography(过长时截取前 60 字),头衔不放入本列
  • 影响力评分:xScore 四舍五入取整,格式 99/100
  • X粉丝数:≥1亿 显示 x.x亿+,≥1万 显示 x,xxxw+
  • 其他平台粉丝数:逐条展示 otherNetworks[].network 平台名 + followersFmt(如 YouTube 400w+;字段名是 network,不是 platform),多个平台用 / 连接,无则 —
  • 专题标签:取专题话题 topics,无则取公益标签 cause,均无则 —
  • 完整性:表格 10 列全部输出,不得为压缩列宽省略任何字段或整列;HTML 报告与对话表格版式保持一致(头衔在账号名下方,简介列仅 biography)

输出完榜单后追加:

总结榜单构成
{AI 对榜单数据做一些分析:头部集中度、行业分布、国家分布、涨粉亮点等}

⚡ 更多操作
• 点击下方下载 HTML 报告文件,可在浏览器中打开查看,支持一键导出 PDF / 高清图片
• 本次榜单完整共 {total} 条数据,是否需要继续查看第 {pageNum+1} 页?

📬 订阅服务
1️⃣ 是否需要订阅每日 X(Twitter) 账号最新排名,订阅后定时推送给您(每日早上 9:00 更新前一天榜单)。
2️⃣ 支持您按照以下筛选项订阅:
   • 性别:全部 / 男 / 女
   • 行业分类:全部行业、商业创业、汽车出行、设计创意、航空领域、电商零售、教育培训、工程运营、娱乐文化、环境能源、家庭育儿、时尚美妆、金融投资、美食饮品、游戏电竞、健康医疗、牧场马术、宗教信仰、科学学术、体育健身、科技软件、旅行户外、视觉艺术、健康生活、居家手工、人力职场、公益平权、法律法务、市场营销、音乐领域、萌宠动物、政治新闻

5. 使用场景

用户分层 核心痛点 使用方式
出海内容创作者 不知道同赛道头部账号是谁、无从对标 查询 "科技类 Twitter 榜单",获取对标参考
品牌方 / 海外投放 找海外达人效率低、不了解账号跨平台影响力 查询 "美妆类女博主榜单",评估投放候选
MCN / 跨境运营团队 竞品账号情报获取难 查询 "宠物榜第2页",逐页监控市场
行业分析师 数据维度单一、缺乏可视化报告 生成 "金融投资行业榜单 HTML 报告"

预期收益:快速掌握 X 平台头部账号格局、识别高增长账号、降低海外投放决策成本。


6. 项目架构

目录结构

x-top-account/
├── SKILL.md                          # 本文件
├── scripts/
│   ├── fetch_rank.py                 # 查询榜单数据(解析/翻页/容错回退)
│   └── generate_report.py            # 生成 X 风格 HTML 报告(导出 PDF/图片)
├── assets/
│   └── category_config.json          # 更新规则 + 性别/行业枚举与关键词映射
├── output/                           # HTML 报告输出目录(运行时自动创建)
└── references/
    ├── category_map.md               # 行业映射表与匹配规则
    └── api_docs.md                   # API 接口详细文档(技术参考)

核心模块说明

  • fetch_rank.py:接收用户查询参数,调用红狐 API 获取榜单数据,自动解析日期、性别、行业与页码,目标日期无数据时自动回退最近可用日期,输出 JSON 数据文件;加 --html 自动调用报告生成。
  • generate_report.py:读取 JSON 数据生成 X 平台风格(纯白底 + X 蓝)HTML 报告,报告标题格式 X(Twitter)·{行业}·热门{性别}账号榜(行业/性别为 all 时省略对应字段),默认保存到 skill 目录下 output/(自动创建),文件名格式 X账号榜_{性别}_{分类}_{日期}.html(性别/分类为 all 时展示为全部性别/全部分类,如 X账号榜_全部性别_全部分类_2026-09-21.html)。列版式与对话表格一致:账号名列展示头像 + 账号名(可点击跳转 X 主页)+ 头衔(账号名下方,超长省略号、悬停显示全文),账号简介列仅 biography(悬停显示全文),其他平台粉丝数带平台名且可点击跳转对应主页;内置导出 PDF / 高清图片按钮,生成后自动打开浏览器。

资源索引

文件 用途
scripts/fetch_rank.py 查询榜单数据
scripts/generate_report.py 生成 HTML 可视化报告
references/category_map.md 行业映射表与匹配规则
references/api_docs.md API 接口详细文档(技术参考)

7. 常见问答

安装

Q: 需要安装什么依赖? A: 无需安装第三方依赖,使用 Python 标准库即可运行。

Q: 如何配置 API Key? A: 请前往 红狐hub 获取 API KEY,然后通过环境变量 REDFOX_API_KEY 配置。

使用

Q: 榜单数据什么时候更新? A: 每日早上 9:00 更新前一天榜单。当前时间未到 9:00 时,脚本会自动取前天数据。

Q: 支持哪些筛选? A: 性别 3 项(全部/男/女)+ 行业 32 类,完整列表见 references/category_map.md。

Q: 数据回溯范围? A: 最多回溯过去 7 天;目标日期无数据时自动回退最近可用日期并提示。

Q: 行业识别失败怎么办? A: 无法识别时降级为全部行业,并列出完整行业列表供用户选择。

Q: 每页多少条?如何翻页? A: 每页固定 20 条,共 10 页 200 条;对话中询问用户是否查看下一页,使用 --page N 翻页。

故障排除

Q: HTML 报告生成失败? A: 确保 workspace 有写权限,且 JSON 数据文件路径正确。

Q: 数据不一致? A: 对话展示多少条(每页 20 条),HTML 报告就展示多少条,两者必须一致。翻页后需重新生成对应页报告。

Files (redfox-community)
  • assets
    • category_config.json 4.3 KB
      {
        "update_rule": {
          "update_hour": 9,
          "update_minute": 0,
          "lookback_days": 7,
          "update_note": "每日早上 9:00 更新前一天榜单"
        },
        "genders": [
          {"value": "all", "zh": "全部", "keywords": ["全部", "所有性别", "不分性别", "男女都", "all"]},
          {"value": "female", "zh": "女", "keywords": ["女性", "女生", "女榜", "女", "female"]},
          {"value": "male", "zh": "男", "keywords": ["男性", "男生", "男榜", "男", "male"]}
        ],
        "categories": [
          {"zh": "全部行业", "keywords": ["全部行业", "全品类", "全部", "综合", "所有", "不限"]},
          {"zh": "商业创业", "keywords": ["商业创业", "创业", "商业", "生意", "企业家", "经商"]},
          {"zh": "汽车出行", "keywords": ["汽车出行", "汽车", "车评", "新能源车", "摩托车", "出行", "车"]},
          {"zh": "设计创意", "keywords": ["设计创意", "设计", "创意", "平面设计", "工业设计", "UI设计"]},
          {"zh": "航空领域", "keywords": ["航空领域", "航空", "飞机", "民航", "飞行员", "机场"]},
          {"zh": "电商零售", "keywords": ["电商零售", "电商", "零售", "跨境电商", "直播带货", "网购"]},
          {"zh": "教育培训", "keywords": ["教育培训", "教育", "培训", "考研", "考试", "课程", "老师", "学习"]},
          {"zh": "工程运营", "keywords": ["工程运营", "工程", "运营", "制造", "机械", "运维"]},
          {"zh": "娱乐文化", "keywords": ["娱乐文化", "娱乐", "文化", "明星", "影视", "综艺", "追星", "八卦"]},
          {"zh": "环境能源", "keywords": ["环境能源", "环境", "能源", "气候", "环保", "电力", "光伏"]},
          {"zh": "家庭育儿", "keywords": ["家庭育儿", "育儿", "母婴", "亲子", "宝宝", "早教", "家庭"]},
          {"zh": "时尚美妆", "keywords": ["时尚美妆", "美妆", "时尚", "穿搭", "护肤", "彩妆", "潮流"]},
          {"zh": "金融投资", "keywords": ["金融投资", "金融", "投资", "交易", "股票", "基金", "理财", "加密货币", "财经", "炒股"]},
          {"zh": "美食饮品", "keywords": ["美食饮品", "美食", "饮品", "探店", "烹饪", "咖啡", "烘焙", "吃播", "菜谱"]},
          {"zh": "游戏电竞", "keywords": ["游戏电竞", "游戏", "电竞", "手游", "网游", "主机游戏"]},
          {"zh": "健康医疗", "keywords": ["健康医疗", "医疗", "医学", "医生", "疾病", "药学", "临床"]},
          {"zh": "牧场马术", "keywords": ["牧场马术", "马术", "牧场", "骑马", "马场"]},
          {"zh": "宗教信仰", "keywords": ["宗教信仰", "宗教", "信仰", "灵性", "佛教", "基督教"]},
          {"zh": "科学学术", "keywords": ["科学学术", "科学", "学术", "科研", "物理", "化学", "天文", "学者"]},
          {"zh": "体育健身", "keywords": ["体育健身", "体育", "健身", "运动", "篮球", "足球", "跑步", "瑜伽", "球赛"]},
          {"zh": "科技软件", "keywords": ["科技软件", "科技", "软件", "编程", "互联网", "人工智能", "AI", "程序员", "数码", "SaaS"]},
          {"zh": "旅行户外", "keywords": ["旅行户外", "旅行", "旅游", "户外", "露营", "徒步", "景点", "攻略"]},
          {"zh": "视觉艺术", "keywords": ["视觉艺术", "绘画", "摄影", "插画", "雕塑", "艺术"]},
          {"zh": "健康生活", "keywords": ["健康生活", "养生", "生活方式", "冥想", "心理健康"]},
          {"zh": "居家手工", "keywords": ["居家手工", "居家", "手工", "手作", "DIY", "家居", "收纳"]},
          {"zh": "人力职场", "keywords": ["人力职场", "人力", "职场", "招聘", "简历", "职业发展", "HR"]},
          {"zh": "公益平权", "keywords": ["公益平权", "公益", "平权", "慈善", "社会责任"]},
          {"zh": "法律法务", "keywords": ["法律法务", "法律", "法务", "律师", "司法", "法规"]},
          {"zh": "市场营销", "keywords": ["市场营销", "营销", "销售", "广告", "品牌", "增长黑客"]},
          {"zh": "音乐领域", "keywords": ["音乐领域", "音乐", "歌手", "乐队", "说唱", "钢琴", "吉他"]},
          {"zh": "萌宠动物", "keywords": ["萌宠动物", "宠物", "萌宠", "猫咪", "狗狗", "猫", "狗", "动物", "兔子"]},
          {"zh": "政治新闻", "keywords": ["政治新闻", "政治", "新闻", "时政", "政策", "记者", "媒体"]}
        ]
      }
      
  • references
    • api_docs.md 4.2 KB
      # X 热门账号榜 API 接口文档
      
      ## 接口基础信息
      
      | 字段 | 值 |
      |------|-----|
      | 接口地址 | `https://redfox.hk/story/api/x/hotAccount/rankList` |
      | 请求方式 | POST |
      | Content-Type | `application/json` |
      | 认证方式 | `X-API-KEY`(从环境变量 `REDFOX_API_KEY` 获取,格式 `ak_xxxxxxxx`) |
      
      ---
      
      ## 请求参数
      
      ```json
      {
        "pageNum": 1,                  // 页码,从 1 开始(每页固定 20 条)
        "rankDate": "2026-09-20",     // 榜单日期 YYYY-MM-DD
        "gender": "all",              // 性别:all / male / female
        "category": "all",            // 行业分类:all 或行业中文名(如 "萌宠动物")
        "source": "X账号榜-GitHub"     // 固定来源标识,每次请求必传
      }
      ```
      
      > ⚠️ **重要**:`category` 传**行业中文名**(如用户问宠物 → 传 `"萌宠动物"`),全部行业传 `"all"`;skill 内部不暴露英文分类值。
      
      ---
      
      ## 响应结构
      
      ```json
      {
        "code": 2000,
        "msg": null,
        "data": {
          "pageNum": 1,
          "pageSize": 20,
          "pages": 10,
          "total": 200,
          "list": [
            {
              "rankNo": 1,
              "fullName": "Donald J. Trump",
              "profileUrl": "https://www.twitter.com/realdonaldtrump/",
              "pictureUrl": "https://favikon-medias.s3.../25073877.jpg",
              "title": "Former U.S. President and Political Leader",
              "biography": "Donald J. Trump is the 45th and 47th President...",
              "countryCode": "us",
              "countryName": "United States",
              "gender": "male",
              "xScore": 98.6,
              "growthPercentage": "+0.11 %",
              "growthAbsolute": "+186.1K",
              "xFollowerCount": 111800000,
              "statDate": "2026-09-20",
              "typologie": null,
              "categoriesJson": "[{\"root_name\":\"⚖️ Law, Medias & Politics\",\"name\":\"Politicians\",\"primary\":true,...}]",
              "networksJson": "{\"youtube\":{\"follower_count\":\"4M\",\"profile_url\":\"...\"},\"twitter\":{...},\"tiktok\":{...}}",
              "badgesJson": "{\"hasTopics\":\"US Elections 2024, Trump Government\",\"hasCause\":\"Conservatives,...\",\"verifiedCreator\":false,...}"
            }
          ]
        }
      }
      ```
      
      ---
      
      ## 错误码
      
      | code | 含义 |
      |------|------|
      | 2000 | **成功**(注意:成功码是 2000 不是 0!) |
      | 其他 | 错误;目标日期/筛选无数据时 `data.list` 为空数组、`total=0` |
      
      ---
      
      ## 字段映射(fetch_rank.py normalized JSON)
      
      | 接口原始字段 | normalized 字段 | 含义 |
      |------------|----------------|------|
      | `rankNo` | `rank` | 排名 |
      | `fullName` | `fullName` | 账号名 |
      | `profileUrl` | `profileUrl` | X 主页链接 |
      | `pictureUrl` | `pictureUrl` | 头像 |
      | `title` | `title` | 头街(一句话介绍) |
      | `biography` | `biography` | 账号简介 |
      | `countryName` / `countryCode` | `country` / `countryCode` | 国家/地区 |
      | `categoriesJson`(primary=true 的 root_name,去 emoji) | `industries` | 主行业 |
      | `xScore` | `score` | 影响力评分(满分 100) |
      | `growthPercentage` | `growthPercentage` | 日涨幅(去空格,如 `+0.11%`) |
      | `growthAbsolute` | `growthAbsolute` | 日涨粉绝对值 |
      | `xFollowerCount` | `xFollowers` / `xFollowersFmt` | X 粉丝数(原始值 / 格式化) |
      | `networksJson`(除 twitter 外) | `otherNetworks` | 其他平台粉丝数列表 |
      | `badgesJson.hasTopics` / `hasCause` | `topics` / `cause` | 专题标签 / 公益标签 |
      
      **JSON 字符串字段**:`categoriesJson`、`networksJson`、`badgesJson` 均为 JSON 字符串,需二次 `json.loads` 解析;解析失败时按空值容错处理。
      
      **头像时效**:`pictureUrl` 为 S3 签名 URL(有效期约 15 分钟),HTML 报告内置 `onerror` 容错,头像失效时自动隐藏、不影响排版。
      
      ---
      
      ## 更新规则与日期计算
      
      | 规则 | 值 |
      |------|-----|
      | 更新时间 | 每日早上 9:00 更新前一天榜单 |
      | 最新可用日期 | 当前时间 ≥ 9:00 → 昨日;< 9:00 → 前日 |
      | 回溯范围 | 过去 7 天 |
      | 空数据回退 | 目标日期 `total=0` 时,自最新可用日期向前逐日扫描(最多 7 天) |
      
      ---
      
      ## 分页规则
      
      | 字段 | 值 |
      |------|-----|
      | pageSize | 固定 20 |
      | pages | 10(全量 200 条) |
      | 翻页方式 | 请求参数 `pageNum` 递增;对话中逐页展示并询问是否继续 |
      
    • category_map.md 3.6 KB
      # 行业分类映射表与匹配规则
      
      ## 传参规则
      
      - 接口 `category` 参数传**行业中文名**(如 `"萌宠动物"`),全部行业传 `"all"`
      - 用户自然语言描述 → 按关键词模糊匹配到行业 → 传对应中文名
      - 例:用户问"宠物" → 传 `"萌宠动物"`;未提及行业 → 传 `"all"`
      - 无法识别时降级为 `all`(全部行业),并列出完整行业列表供用户选择
      - skill 内部(文档、配置、输出)不暴露英文分类值
      
      ## 性别映射
      
      | 用户说 | 传参 | 展示 |
      |--------|------|------|
      | 男、男性、男生、男榜 | `male` | 男 |
      | 女、女性、女生、女榜 | `female` | 女 |
      | 全部、不分性别、未提及 | `all` | 全部 |
      
      ## 行业分类表(32 类)
      
      | 传参值(中文) | 常见用户说法(模糊匹配关键词) |
      |--------------|------------------------------|
      | `all`(全部行业) | 全部、全品类、综合、所有、不限 |
      | `商业创业` | 创业、商业、生意、企业家、经商 |
      | `汽车出行` | 汽车、车评、新能源车、摩托车、出行 |
      | `设计创意` | 设计、创意、平面设计、工业设计、UI设计 |
      | `航空领域` | 航空、飞机、民航、飞行员、机场 |
      | `电商零售` | 电商、零售、跨境电商、直播带货、网购 |
      | `教育培训` | 教育、培训、考研、考试、课程、老师、学习 |
      | `工程运营` | 工程、运营、制造、机械、运维 |
      | `娱乐文化` | 娱乐、文化、明星、影视、综艺、追星、八卦 |
      | `环境能源` | 环境、能源、气候、环保、电力、光伏 |
      | `家庭育儿` | 育儿、母婴、亲子、宝宝、早教、家庭 |
      | `时尚美妆` | 美妆、时尚、穿搭、护肤、彩妆、潮流 |
      | `金融投资` | 金融、投资、交易、股票、基金、理财、加密货币、财经、炒股 |
      | `美食饮品` | 美食、饮品、探店、烹饪、咖啡、烘焙、吃播、菜谱 |
      | `游戏电竞` | 游戏、电竞、手游、网游、主机游戏 |
      | `健康医疗` | 医疗、医学、医生、疾病、药学、临床 |
      | `牧场马术` | 马术、牧场、骑马、马场 |
      | `宗教信仰` | 宗教、信仰、灵性、佛教、基督教 |
      | `科学学术` | 科学、学术、科研、物理、化学、天文、学者 |
      | `体育健身` | 体育、健身、运动、篮球、足球、跑步、瑜伽、球赛 |
      | `科技软件` | 科技、软件、编程、互联网、人工智能、AI、程序员、数码、SaaS |
      | `旅行户外` | 旅行、旅游、户外、露营、徒步、景点、攻略 |
      | `视觉艺术` | 绘画、摄影、插画、雕塑、艺术 |
      | `健康生活` | 养生、生活方式、冥想、心理健康 |
      | `居家手工` | 居家、手工、手作、DIY、家居、收纳 |
      | `人力职场` | 人力、职场、招聘、简历、职业发展、HR |
      | `公益平权` | 公益、平权、慈善、社会责任 |
      | `法律法务` | 法律、法务、律师、司法、法规 |
      | `市场营销` | 营销、销售、广告、品牌、增长黑客 |
      | `音乐领域` | 音乐、歌手、乐队、说唱、钢琴、吉他 |
      | `萌宠动物` | 宠物、萌宠、猫咪、狗狗、猫、狗、动物、兔子 |
      | `政治新闻` | 政治、新闻、时政、政策、记者、媒体 |
      
      ## 匹配策略
      
      - **长词优先**:所有关键词按长度降序扫描,先命中长者(如 "健康生活" 优先于 "健康")
      - **全文扫描**:关键词出现在用户文本任意位置即命中
      - **显式优先**:`--category` 参数支持直接传行业中文名或匹配关键词,优先级高于文本解析
      - **降级兜底**:无任何命中时传 `all`,并在对话中告知用户当前为全部行业榜单
      
  • scripts
    • fetch_rank.py 14.8 KB
      #!/usr/bin/env python3
      """
      X (Twitter) 热门账号榜数据抓取脚本
      用法:
          python fetch_rank.py --query "给我2026年4月25日的Twitter全品类日榜"
          python fetch_rank.py --query "宠物类女博主榜单" --page 2 --html
          python fetch_rank.py --date 2026-09-20 --gender female --category "萌宠动物"
      """
      import argparse
      import json
      import os
      import re
      import subprocess
      import sys
      from datetime import date, datetime, timedelta
      
      import urllib.request
      import urllib.error
      
      API_URL = "https://redfox.hk/story/api/x/hotAccount/rankList"
      
      # ─────────────────────────────────────────────────────────
      # 加载外部静态配置(assets/)
      # ─────────────────────────────────────────────────────────
      _ASSETS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "assets")
      _SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
      OUTPUT_DIR = os.path.join(_SKILL_DIR, "output")  # 数据与报告统一落盘 output/,不污染 skill 根目录
      
      
      def _load_json(filename):
          with open(os.path.join(_ASSETS_DIR, filename), encoding="utf-8") as f:
              return json.load(f)
      
      
      _cfg = _load_json("category_config.json")
      UPDATE_HOUR = _cfg["update_rule"]["update_hour"]
      UPDATE_MINUTE = _cfg["update_rule"]["update_minute"]
      LOOKBACK_DAYS = _cfg["update_rule"]["lookback_days"]
      UPDATE_NOTE = _cfg["update_rule"]["update_note"]
      GENDERS = _cfg["genders"]
      CATEGORIES = _cfg["categories"]
      
      GENDER_LABELS = {g["value"]: g["zh"] for g in GENDERS}
      ALL_CATEGORY_ZH = "全部行业"
      CATEGORY_BY_ZH = {c["zh"]: c for c in CATEGORIES}
      
      CN_NUM = {"一": 1, "二": 2, "三": 3, "四": 4, "五": 5,
                "六": 6, "七": 7, "八": 8, "九": 9, "十": 10}
      
      
      def _get_api_key():
          """从环境变量 REDFOX_API_KEY 获取 API Key。"""
          api_key = os.environ.get("REDFOX_API_KEY", "").strip()
          if api_key:
              return api_key
          print("[ERROR] 未设置 REDFOX_API_KEY 环境变量", file=sys.stderr)
          print("[HINT] 请运行: export REDFOX_API_KEY=<你的apikey>", file=sys.stderr)
          print("[HINT] 访问 https://redfox.hk/settings/api-keys?source=github 获取 API Key", file=sys.stderr)
          sys.exit(4)
      
      
      def _api_post(payload, timeout=20):
          """使用原生 urllib 发送 HTTPS POST 请求,携带 X-API-KEY 鉴权。"""
          headers = {
              "Content-Type": "application/json",
              "Accept": "application/json",
              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
              "X-API-KEY": _get_api_key(),
          }
          data = json.dumps(payload).encode("utf-8")
          req = urllib.request.Request(API_URL, data=data, headers=headers, method="POST")
          try:
              with urllib.request.urlopen(req, timeout=timeout) as resp:
                  return 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[:200]}", file=sys.stderr)
              sys.exit(2)
      
      
      # ─────────────────────────────────────────────────────────
      # 自然语言解析:性别 / 行业 / 日期 / 页码
      # ─────────────────────────────────────────────────────────
      def match_gender(text, explicit=None):
          if explicit:
              return explicit
          low = (text or "").lower()
          for g in GENDERS:  # 配置中 female 先于 male,避免"女"被"男"误吞
              if g["value"] == "all":
                  continue
              for kw in g["keywords"]:
                  if kw.lower() in low:
                      return g["value"]
          return "all"
      
      
      def match_category(text, explicit=None):
          """返回接口 category 传参值:"all" 或行业中文名。"""
          if explicit:
              key = explicit.strip()
              if key in ("all", ALL_CATEGORY_ZH):
                  return "all"
              if key in CATEGORY_BY_ZH:
                  return key
              for c in CATEGORIES:  # 支持传匹配关键词
                  if key in c["keywords"]:
                      return "all" if c["zh"] == ALL_CATEGORY_ZH else c["zh"]
              print(f"[WARN] 无法识别的行业分类「{explicit}」,已降级为全部行业", file=sys.stderr)
              return "all"
          low = (text or "").lower()
          pairs = []
          for c in CATEGORIES:
              if c["zh"] == ALL_CATEGORY_ZH:
                  continue
              for kw in c["keywords"]:
                  pairs.append((kw.lower(), c["zh"]))
          pairs.sort(key=lambda p: len(p[0]), reverse=True)  # 长词优先
          for kw, zh in pairs:
              if kw in low:
                  return zh
          return "all"
      
      
      def parse_page(text, explicit=None):
          if explicit:
              return max(1, int(explicit))
          m = re.search(r"第\s*([0-9]+|[一二三四五六七八九十])\s*页", text or "")
          if m:
              v = m.group(1)
              return CN_NUM.get(v, int(v) if v.isdigit() else 1)
          return 1
      
      
      def parse_date(text, explicit=None):
          if explicit:
              return date.fromisoformat(explicit)
          t = text or ""
          if "前天" in t:
              return date.today() - timedelta(days=2)
          if "昨天" in t or "昨日" in t:
              return date.today() - timedelta(days=1)
          if "今天" in t or "今日" in t:
              return date.today()
          m = re.search(r"(20\d{2})\s*[-年/.]\s*(\d{1,2})\s*[-月/.]\s*(\d{1,2})", t)
          if m:
              return date(int(m.group(1)), int(m.group(2)), int(m.group(3)))
          m = re.search(r"(\d{1,2})\s*[-月/.]\s*(\d{1,2})\s*日?", t)
          if m:
              return date(date.today().year, int(m.group(1)), int(m.group(2)))
          return None
      
      
      # ─────────────────────────────────────────────────────────
      # 日期计算与容错回退
      # ─────────────────────────────────────────────────────────
      def latest_rank_date():
          """每日早上 9:00 更新前一天榜单:9 点后最新为昨日,9 点前为前日。"""
          now = datetime.now()
          updated = (now.hour, now.minute) >= (UPDATE_HOUR, UPDATE_MINUTE)
          offset = 1 if updated else 2
          return date.today() - timedelta(days=offset)
      
      
      def fetch_page(rank_date, gender, category, page):
          """请求单页榜单,返回 data dict;无数据或失败返回 None。"""
          payload = {
              "pageNum": page,
              "rankDate": str(rank_date),
              "gender": gender,
              "category": category,
              "source": "X账号榜-GitHub",
          }
          resp = _api_post(payload)
          if resp.get("code") != 2000:
              print(f"[ERROR] 接口返回异常 code={resp.get('code')} msg={resp.get('msg')}", file=sys.stderr)
              return None
          data = resp.get("data") or {}
          if not data.get("list"):
              return None
          return data
      
      
      def resolve_date(target, gender, category, page, warnings):
          """校验目标日期并容错回退到最近可用日期。"""
          today = date.today()
          if target is None:
              target = latest_rank_date()
          else:
              diff = (today - target).days
              if diff < 1:
                  warnings.append("非常抱歉🙏,我们最新的是昨日的数据,将为您提供最接近您需求的昨日热榜。")
                  target = latest_rank_date()
              elif diff > LOOKBACK_DAYS:
                  warnings.append(f"非常抱歉🙏,目前榜单最多支持回溯「过去{LOOKBACK_DAYS}天」,我将为您查询最接近您需求的时间范围~")
                  target = latest_rank_date()
      
          data = fetch_page(target, gender, category, page)
          if data:
              return target, data
      
          # 目标日期暂无数据:自最新可用日期起向前扫描回退
          start = latest_rank_date()
          for i in range(LOOKBACK_DAYS):
              cand = start - timedelta(days=i)
              data = fetch_page(cand, gender, category, page)
              if data:
                  if cand != target:
                      warnings.append(f"「{target}」暂无榜单数据,已自动切换至最近可用日期 {cand}。")
                  return cand, data
          return target, None
      
      
      # ─────────────────────────────────────────────────────────
      # 字段归一化
      # ─────────────────────────────────────────────────────────
      def _strip_emoji(s):
          return re.sub(r"[^\x20-\x7E\u4e00-\u9fff]", "", s or "").strip()
      
      
      def _safe_json(s, default):
          """解析 JSON 字符串字段;兼容双重编码,类型不符时回退默认值。"""
          cur = s
          for _ in range(3):
              if not isinstance(cur, str):
                  break
              try:
                  cur = json.loads(cur)
              except (ValueError, TypeError):
                  return default
          if isinstance(default, dict) and not isinstance(cur, dict):
              return default
          if isinstance(default, list) and not isinstance(cur, list):
              return default
          return cur
      
      
      def fmt_followers(n):
          """111800000 -> 1.1亿+;31000000 -> 3,100w+;1800000 -> 180w+"""
          try:
              n = int(n)
          except (ValueError, TypeError):
              return "-"
          if n >= 100000000:
              return f"{n / 100000000:.1f}亿+"
          if n >= 10000:
              return f"{n // 10000:,}w+"
          return str(n)
      
      
      def parse_count(s):
          """解析接口粉丝数字符串:4M -> 4000000;290K -> 290000;4.4M -> 4400000"""
          if not s or s == "-":
              return None
          m = re.match(r"^([\d.]+)\s*([KMB]?)$", str(s).strip(), re.IGNORECASE)
          if not m:
              return None
          mult = {"": 1, "K": 1000, "M": 1000000, "B": 1000000000}[m.group(2).upper()]
          return int(float(m.group(1)) * mult)
      
      
      _NETWORK_ORDER = ["youtube", "tiktok", "instagram", "twitch", "linkedin", "facebook"]
      _NETWORK_LABELS = {"youtube": "YouTube", "tiktok": "TikTok", "instagram": "Instagram",
                         "twitch": "Twitch", "linkedin": "LinkedIn", "facebook": "Facebook"}
      
      
      def normalize_item(raw):
          cats = _safe_json(raw.get("categoriesJson"), [])
          industries, seen = [], set()
          for c in cats:
              if c.get("primary"):
                  name = _strip_emoji(c.get("root_name"))
                  if name and name not in seen:
                      seen.add(name)
                      industries.append(name)
          if not industries and cats:
              industries = [_strip_emoji(cats[0].get("root_name"))]
      
          networks = _safe_json(raw.get("networksJson"), {}) or {}
          others = []
          for key in _NETWORK_ORDER + [k for k in networks if k not in _NETWORK_ORDER]:
              v = networks.get(key)
              if not v or key == "twitter":
                  continue
              fc = v.get("follower_count") or "-"
              cnt = parse_count(fc)
              others.append({
                  "network": _NETWORK_LABELS.get(key, key.capitalize()),
                  "followers": fc,
                  "followersFmt": fmt_followers(cnt) if cnt is not None else fc,
                  "profileUrl": v.get("profile_url") or "",
              })
      
          badges = _safe_json(raw.get("badgesJson"), {}) or {}
          growth = (raw.get("growthPercentage") or "").replace(" ", "")
      
          return {
              "rank": raw.get("rankNo"),
              "fullName": raw.get("fullName") or "-",
              "profileUrl": raw.get("profileUrl") or "",
              "pictureUrl": raw.get("pictureUrl") or "",
              "title": raw.get("title") or "",
              "biography": raw.get("biography") or "",
              "country": raw.get("countryName") or "-",
              "countryCode": (raw.get("countryCode") or "").lower(),
              "gender": raw.get("gender") or "",
              "industries": industries,
              "score": raw.get("xScore"),
              "growthPercentage": growth,
              "growthAbsolute": raw.get("growthAbsolute") or "",
              "xFollowers": raw.get("xFollowerCount"),
              "xFollowersFmt": fmt_followers(raw.get("xFollowerCount")),
              "otherNetworks": others,
              "topics": badges.get("hasTopics") or "",
              "cause": badges.get("hasCause") or "",
          }
      
      
      def main():
          parser = argparse.ArgumentParser(description="X (Twitter) 热门账号榜查询")
          parser.add_argument("--query", default="", help="用户原始问题(自动解析日期/性别/行业/页码)")
          parser.add_argument("--date", default=None, help="榜单日期 YYYY-MM-DD")
          parser.add_argument("--gender", default=None, choices=["all", "male", "female"])
          parser.add_argument("--category", default=None, help="行业分类(中文名,如 萌宠动物;默认全部行业)")
          parser.add_argument("--page", type=int, default=None, help="页码(每页 20 条)")
          parser.add_argument("--output", default=None, help="JSON 输出路径")
          parser.add_argument("--html", action="store_true", help="同时生成 HTML 报告")
          args = parser.parse_args()
      
          gender = match_gender(args.query, args.gender)
          category = match_category(args.query, args.category)
          page = parse_page(args.query, args.page)
          target = parse_date(args.query, args.date)
      
          warnings = []
          rank_date, data = resolve_date(target, gender, category, page, warnings)
          if not data:
              print("[ERROR] 该筛选条件下暂无榜单数据,请更换日期/性别/行业后重试", file=sys.stderr)
              sys.exit(3)
      
          items = [normalize_item(x) for x in data.get("list", [])]
          meta = {
              "rankDate": str(rank_date),
              "gender": gender,
              "genderLabel": GENDER_LABELS.get(gender, "全部"),
              "category": category,
              "categoryLabel": ALL_CATEGORY_ZH if category == "all" else category,
              "pageNum": data.get("pageNum", page),
              "pageSize": data.get("pageSize", 20),
              "pages": data.get("pages", 1),
              "total": data.get("total", len(items)),
              "updateNote": UPDATE_NOTE,
              "warnings": warnings,
              "generatedAt": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
          }
          result = {"meta": meta, "items": items}
      
          out_path = args.output or os.path.join(OUTPUT_DIR, "x_top_account_data.json")
          out_dir = os.path.dirname(out_path)
          if out_dir:
              os.makedirs(out_dir, exist_ok=True)
          with open(out_path, "w", encoding="utf-8") as f:
              json.dump(result, f, ensure_ascii=False, indent=2)
      
          for w in warnings:
              print(f"[WARN] {w}")
          print(f"[INFO] 数据日期:{meta['rankDate']}|性别:{meta['genderLabel']}|行业:{meta['categoryLabel']}"
                f"|第 {meta['pageNum']}/{meta['pages']} 页|共 {meta['total']} 条")
          print(f"[INFO] 数据文件:{out_path}")
      
          if args.html:
              script = os.path.join(os.path.dirname(os.path.abspath(__file__)), "generate_report.py")
              subprocess.run([sys.executable, script, "--data", out_path], check=False)
      
      
      if __name__ == "__main__":
          main()
      
    • generate_report.py 13.9 KB
      #!/usr/bin/env python3
      """
      X (Twitter) 热门账号榜 HTML 报告生成脚本
      用法:
          python generate_report.py --data /path/to/x_top_account_data.json
          python generate_report.py --data data.json --output /path/to/report.html
      X 平台风格(纯白底 + X 蓝 #1d9bf0),支持一键导出 PDF / 高清图片。
      """
      import argparse
      import html
      import json
      import os
      import subprocess
      import sys
      from datetime import datetime
      
      # X 平台视觉规范
      X_BLUE = "#1d9bf0"
      X_TEXT = "#0f1419"
      X_SUB = "#536471"
      X_BORDER = "#eff3f4"
      X_HOVER = "#f7f9f9"
      X_GREEN = "#00ba7c"
      X_RED = "#f4212e"
      
      # HTML 报告默认输出目录:skill 目录下的 output/(运行时自动创建)
      _SKILL_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
      OUTPUT_DIR = os.path.join(_SKILL_DIR, "output")
      
      MEDALS = {1: ("🥇", "#ffd700"), 2: ("🥈", "#c0c0c0"), 3: ("🥉", "#cd7f32")}
      
      
      def esc(s):
          return html.escape(str(s if s is not None else ""), quote=True)
      
      
      def flag_emoji(cc):
          cc = (cc or "").upper()
          if len(cc) != 2 or not cc.isalpha():
              return ""
          return "".join(chr(0x1F1E6 + ord(ch) - 65) for ch in cc)
      
      
      def score_fmt(score):
          try:
              return f"{round(float(score))}/100"
          except (TypeError, ValueError):
              return "-"
      
      
      def growth_html(g):
          g = (g or "").strip()
          if not g:
              return "<span class='dim'>—</span>"
          cls = "up" if g.startswith("+") else ("down" if g.startswith("-") else "dim")
          return f"<span class='{cls}'>{esc(g)}</span>"
      
      
      CSS = f"""
      * {{ box-sizing: border-box; margin: 0; padding: 0; }}
      body {{
        background: #ffffff; color: {X_TEXT};
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
          "Helvetica Neue", "PingFang SC", "Microsoft YaHei", sans-serif;
        padding: 32px 16px;
      }}
      .report {{ max-width: 1440px; margin: 0 auto; }}
      .header {{ display: flex; align-items: center; gap: 14px; margin-bottom: 6px; }}
      .logo {{
        width: 44px; height: 44px; border-radius: 50%; background: {X_TEXT};
        color: #fff; font-size: 26px; font-weight: 800;
        display: flex; align-items: center; justify-content: center; flex: none;
      }}
      .header h1 {{ font-size: 24px; font-weight: 800; letter-spacing: .2px; }}
      .header .sub {{ color: {X_SUB}; font-size: 13px; margin-top: 4px; }}
      .export-bar {{ text-align: right; margin: 10px 0 14px; }}
      .btn {{
        border: 1px solid {X_BORDER}; background: #fff; color: {X_BLUE};
        border-radius: 999px; padding: 8px 18px; font-size: 13px; font-weight: 700;
        cursor: pointer; margin-left: 8px;
      }}
      .btn-primary {{ background: {X_BLUE}; border-color: {X_BLUE}; color: #fff; }}
      .btn:hover {{ opacity: .85; }}
      .stats {{ display: flex; gap: 12px; flex-wrap: nowrap; margin-bottom: 16px; }}
      .stat {{
        flex: 1; min-width: 150px; background: #fff; border: 1px solid {X_BORDER};
        border-radius: 16px; padding: 14px 18px;
      }}
      .stat .v {{ font-size: 22px; font-weight: 800; color: {X_BLUE}; }}
      .stat .k {{ font-size: 12px; color: {X_SUB}; margin-top: 4px; }}
      .notice {{
        background: {X_HOVER}; border: 1px solid {X_BORDER}; border-radius: 16px;
        padding: 14px 18px; font-size: 13px; color: {X_SUB}; line-height: 1.8;
        margin-bottom: 16px;
      }}
      .notice b {{ color: {X_TEXT}; }}
      .table-wrap {{
        border: 1px solid {X_BORDER}; border-radius: 16px; overflow: hidden;
        background: #fff;
      }}
      table {{ width: 100%; border-collapse: collapse; font-size: 13px; table-layout: fixed; }}
      thead th:nth-child(1) {{ width: 56px; }}
      thead th:nth-child(2) {{ width: 186px; }}
      thead th:nth-child(3) {{ width: 194px; }}
      thead th:nth-child(4) {{ width: 84px; }}
      thead th:nth-child(5) {{ width: 128px; }}
      thead th:nth-child(6) {{ width: 84px; }}
      thead th:nth-child(7) {{ width: 76px; }}
      thead th:nth-child(8) {{ width: 84px; }}
      thead th:nth-child(9) {{ width: 150px; }}
      thead th:nth-child(10) {{ width: 150px; }}
      thead th {{
        background: {X_HOVER}; color: {X_SUB}; font-size: 12px; font-weight: 700;
        text-align: left; padding: 12px 10px; border-bottom: 1px solid {X_BORDER};
      }}
      tbody td {{ padding: 12px 10px; border-bottom: 1px solid {X_BORDER}; vertical-align: top; }}
      tbody tr:last-child td {{ border-bottom: none; }}
      tbody tr:hover {{ background: {X_HOVER}; }}
      .rank {{ font-weight: 800; font-size: 15px; white-space: nowrap; }}
      .acct {{ display: flex; align-items: center; gap: 8px; min-width: 0; max-width: 100%; }}
      .acct img {{
        width: 28px; height: 28px; border-radius: 50%; object-fit: cover; flex: none;
        background: {X_BORDER};
      }}
      .acct a {{
        color: {X_BLUE}; text-decoration: none; font-weight: 700;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block;
      }}
      .acct a:hover {{ text-decoration: underline; }}
      .bio {{ max-width: 100%; color: {X_SUB}; font-size: 12px; line-height: 1.6; }}
      .acct-body {{ min-width: 0; max-width: 100%; }}
      .acct .t {{
        color: {X_SUB}; font-size: 12px; margin-top: 2px;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
      }}
      .bio .d {{
        display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
        overflow: hidden;
      }}
      .ind {{ color: {X_SUB}; font-size: 12px; line-height: 1.6; word-break: break-word; }}
      .score {{ font-weight: 800; white-space: nowrap; }}
      .up {{ color: {X_GREEN}; font-weight: 700; white-space: nowrap; }}
      .down {{ color: {X_RED}; font-weight: 700; white-space: nowrap; }}
      .dim {{ color: {X_SUB}; }}
      .fans {{ font-weight: 700; white-space: nowrap; }}
      .nets {{ margin: 0; padding-left: 16px; color: {X_SUB}; font-size: 12px; line-height: 1.7; word-break: break-word; }}
      .nets a {{ color: {X_SUB}; text-decoration: none; }}
      .nets a:hover {{ color: {X_BLUE}; }}
      .tags {{ color: {X_SUB}; font-size: 12px; max-width: 100%; word-break: break-word; }}
      .footer {{
        margin-top: 18px; color: {X_SUB}; font-size: 12px; text-align: center; line-height: 1.8;
      }}
      @media (max-width: 768px) {{
        .stats {{ flex-wrap: wrap; }}
      }}
      @media print {{
        .export-bar {{ display: none; }}
        body {{ padding: 0; }}
        .table-wrap {{ box-shadow: none; }}
      }}
      """
      
      
      def build_rows(items):
          rows = []
          for it in items:
              rank = it.get("rank")
              medal = MEDALS.get(rank)
              rank_cell = f"<span>{medal[0]} {rank}</span>" if medal else f"<span class='dim'>{rank}</span>"
      
              name = esc(it.get("fullName"))
              url = esc(it.get("profileUrl"))
              pic = esc(it.get("pictureUrl"))
              avatar = f"<img src='{pic}' alt='' onerror=\"this.style.visibility='hidden'\">" if pic else ""
              title = esc(it.get("title"))
              acct = (f"<div class='acct'>{avatar}<div class='acct-body'>"
                      f"<a href='{url}' target='_blank' rel='noopener' title='{name}'>{name}</a>"
                      f"<div class='t' title='{title}'>{title or '—'}</div></div></div>")
      
              bio_full = esc(it.get("biography"))
              bio = f"<div class='bio'><div class='d' title='{bio_full}'>{bio_full}</div></div>"
      
              flag = flag_emoji(it.get("countryCode"))
              country = f"{flag} {esc(it.get('country'))}".strip()
      
              inds = it.get("industries") or []
              ind = esc(" / ".join(inds[:2])) if inds else "<span class='dim'>—</span>"
      
              nets = it.get("otherNetworks") or []
              if nets:
                  lis = "".join(
                      f"<li><a href='{esc(n.get('profileUrl'))}' target='_blank' rel='noopener'>"
                      f"{esc(n.get('network'))} {esc(n.get('followersFmt') or n.get('followers'))}</a></li>"
                      for n in nets)
                  nets_cell = f"<ul class='nets'>{lis}</ul>"
              else:
                  nets_cell = "<span class='dim'>—</span>"
      
              topics = it.get("topics") or it.get("cause") or ""
              tags = esc(topics) if topics else "<span class='dim'>—</span>"
      
              rows.append(
                  "<tr>"
                  f"<td class='rank'>{rank_cell}</td>"
                  f"<td>{acct}</td>"
                  f"<td>{bio}</td>"
                  f"<td>{country}</td>"
                  f"<td class='ind'>{ind}</td>"
                  f"<td class='score'>{score_fmt(it.get('score'))}</td>"
                  f"<td>{growth_html(it.get('growthPercentage'))}</td>"
                  f"<td class='fans'>{esc(it.get('xFollowersFmt'))}</td>"
                  f"<td>{nets_cell}</td>"
                  f"<td class='tags'>{tags}</td>"
                  "</tr>")
          return "\n".join(rows)
      
      
      def build_html(payload):
          meta = payload.get("meta", {})
          items = payload.get("items", [])
      
          scores = [float(i["score"]) for i in items if i.get("score") is not None]
          avg_score = f"{sum(scores) / len(scores):.1f}" if scores else "-"
          growths = []
          for i in items:
              g = (i.get("growthPercentage") or "").replace("%", "").replace("+", "")
              try:
                  growths.append((float(g), i.get("fullName")))
              except ValueError:
                  pass
          top_growth = f"+{max(growths)[0]}% · {max(growths)[1]}" if growths else "-"
      
          rows = build_rows(items)
          now = datetime.now().strftime("%Y-%m-%d %H:%M")
          img_name = esc(report_filename(meta)[:-5] + ".png")
      
          # 标题:X(Twitter)·{行业}·热门{性别}账号榜;行业/性别为 all 时省略对应字段
          gender_zh = {"male": "男", "female": "女"}.get(meta.get("gender", "all"), "")
          cat_part = f"·{meta.get('categoryLabel')}" if meta.get("category") != "all" else ""
          rank_part = f"热门{gender_zh}性账号榜" if gender_zh else "热门账号榜"
          h1 = f"X(Twitter){cat_part}·{rank_part}"
      
          return f"""<!DOCTYPE html>
      <html lang="zh-CN">
      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>{esc(h1)} · {esc(meta.get('rankDate'))}</title>
      <style>{CSS}</style>
      </head>
      <body>
      <div class="report" id="report">
        <div class="header">
          <div class="logo">𝕏</div>
          <div>
            <h1>{esc(h1)}</h1>
            <div class="sub">数据日期 {esc(meta.get('rankDate'))} · 第 {esc(meta.get('pageNum'))}/{esc(meta.get('pages'))} 页 · 每页 {esc(meta.get('pageSize'))} 条 · 影响力评分:结合粉丝数、互动量、曝光数等加权综合评估</div>
          </div>
        </div>
      
        <div class="export-bar">
          <button class="btn btn-primary" onclick="window.print()">🖨️ 导出 PDF</button>
          <button class="btn" id="downloadImgBtn" onclick="downloadAsImage()">📷 导出图片</button>
        </div>
      
        <div class="stats">
          <div class="stat"><div class="v">{esc(meta.get('total'))}</div><div class="k">上榜账号(总)</div></div>
          <div class="stat"><div class="v">{esc(meta.get('pageNum'))}/{esc(meta.get('pages'))}</div><div class="k">当前页 / 总页数</div></div>
          <div class="stat"><div class="v">{avg_score}</div><div class="k">本页平均影响力评分</div></div>
          <div class="stat"><div class="v" style="font-size:15px;line-height:30px;">{esc(top_growth)}</div><div class="k">本页最高日涨幅</div></div>
        </div>
      
        <div class="notice">
          <div>💡 <b>榜单说明</b>:{esc(meta.get('updateNote'))},与实时数据存在差异。</div>
          <div>📐 <b>影响力评分</b>:结合粉丝数、互动量、曝光数等加权综合评估,满分 100。</div>
        </div>
      
        <div class="table-wrap">
          <table>
            <thead>
              <tr>
                <th>排名</th><th>账号名</th><th>账号简介</th><th>国家/地区</th><th>主行业</th>
                <th>影响力评分</th><th>粉丝数日涨幅</th><th>X粉丝数</th><th>其他平台粉丝数</th><th>专题标签</th>
              </tr>
            </thead>
            <tbody>
      {rows}
            </tbody>
          </table>
        </div>
      
        <div class="footer">
          数据来源:红狐数据 · 生成时间 {now}<br>
          本报告支持浏览器一键导出 PDF / 高清图片
        </div>
      </div>
      
      <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
      <script>
      async function downloadAsImage() {{
        const btn = document.getElementById('downloadImgBtn');
        btn.disabled = true; btn.textContent = '⏳ 生成中...';
        try {{
          const canvas = await html2canvas(document.getElementById('report'), {{
            scale: 2, backgroundColor: '#ffffff', useCORS: true
          }});
          const a = document.createElement('a');
          a.download = '{img_name}';
          a.href = canvas.toDataURL('image/png');
          a.click();
        }} catch (e) {{
          alert('图片导出失败:' + e.message + '\\n可改用「导出 PDF」按钮。');
        }} finally {{
          btn.disabled = false; btn.textContent = '📷 导出图片';
        }}
      }}
      </script>
      </body>
      </html>"""
      
      
      def open_in_browser(path):
          try:
              abs_path = os.path.abspath(path)
              if sys.platform == "darwin":
                  subprocess.run(["open", abs_path], check=True)
              elif sys.platform.startswith("win"):
                  os.startfile(abs_path)  # noqa
              else:
                  subprocess.run(["xdg-open", abs_path], check=True)
              print(f"\n✓ HTML 报告已自动打开: {abs_path}", file=sys.stderr)
          except Exception:
              print(f"\n✓ HTML 报告已生成: {os.path.abspath(path)}", file=sys.stderr)
      
      
      def report_filename(meta):
          """报告文件名:X账号榜_性别_分类_日期.html;all 展示为全部性别/全部分类。"""
          gender = meta.get("gender", "all")
          gender_part = "全部性别" if gender == "all" else (meta.get("genderLabel") or gender)
          category = meta.get("category", "all")
          category_part = "全部分类" if category == "all" else (meta.get("categoryLabel") or category)
          return f"X账号榜_{gender_part}_{category_part}_{meta.get('rankDate', 'latest')}.html"
      
      
      def main():
          parser = argparse.ArgumentParser(description="生成 X 热门账号榜 HTML 报告")
          parser.add_argument("--data", required=True, help="fetch_rank.py 输出的 JSON 路径")
          parser.add_argument("--output", default=None, help="HTML 输出路径")
          parser.add_argument("--no-open", action="store_true", help="生成后不自动打开浏览器")
          args = parser.parse_args()
      
          with open(args.data, encoding="utf-8") as f:
              payload = json.load(f)
          meta = payload.get("meta", {})
      
          out = args.output or os.path.join(OUTPUT_DIR, report_filename(meta))
          os.makedirs(os.path.dirname(os.path.abspath(out)), exist_ok=True)
      
          with open(out, "w", encoding="utf-8") as f:
              f.write(build_html(payload))
          print(f"[INFO] HTML 报告已生成:{out}")
      
          if not args.no_open:
              open_in_browser(out)
      
      
      if __name__ == "__main__":
          main()
      
  • README.en.md 6.3 KB
    # X (Twitter) Top Accounts / x-top-account
    
    [中文](README.md) | **English**
    
    ---
    
    ## Introduction
    
    Quickly discover the most influential accounts on X (Twitter) and grasp the global creator landscape.
    
    **Core Value**
    Built on daily TOP-200 influential accounts with follower, growth and cross-platform data, helping you solve benchmarking, overseas advertising, competitor monitoring and industry insight challenges.
    
    **Target Users**
    
    - 🌏 Global content creators — benchmark top accounts in your niche
    - 🏢 Brands / overseas advertisers — screen quality creators and evaluate cross-platform value
    - 📦 MCN / cross-border ops teams — track competitor dynamics
    - 📊 Industry analysts — generate data-driven reports
    
    ---
    
    ## Features
    
    - **Ranking query**: daily X influence ranking, 20 items per page, 10 pages / 200 items in total, with pagination
    - **Filters**: gender (all / male / female) and 32 industry categories, with fuzzy keyword matching (e.g. "pets" → 萌宠动物; category values are passed in Chinese)
    - **Influence score**: weighted evaluation of followers, engagement and impressions, out of 100
    - **HTML report**: X-styled visual HTML report with clickable account links, one-click export to PDF / high-res image
    - **Subscription**: daily scheduled push, combinable with gender / industry filters
    
    ---
    
    ## API Key & Security
    
    - This skill requires the environment variable `REDFOX_API_KEY`.
    - Get your key at [RedFox Hub](https://redfox.hk/settings/api-keys?source=github) (`https://redfox.hk`).
    - Register at [RedFox Hub](https://redfox.hk?source=github) and configure `REDFOX_API_KEY` in your environment.
    - Verify the key's source, scope, validity and revocability before providing it.
    - Never hardcode or expose the key in code, prompts, logs or output files.
    
    ---
    
    ## Usage Guide
    
    Describe your need in natural language — no command syntax to memorize.
    
    ### Quick Examples
    
    | Intent            | Example                                          | Result                              |
    | ----------------- | ------------------------------------------------ | ----------------------------------- |
    | Latest ranking    | "Show me the latest Twitter all-category ranking" | Page 1 (20 items) of latest date   |
    | Industry ranking  | "How do pet accounts rank on Twitter?"            | 萌宠动物 (Pets) ranking              |
    | Gender ranking    | "Top female beauty creators on X"                 | 时尚美妆 (Beauty) + female filter    |
    | Specific date     | "Twitter ranking for Sep 20, 2026"                | Ranking of the given date          |
    | Pagination        | "Show me page 2"                                  | Page 2 (20 items)                  |
    | Report download   | "Generate the HTML report for this ranking"       | Visual HTML file delivered         |
    | Subscription      | "Send me the pet ranking every day"               | Scheduled push task created        |
    
    ### Output Example
    
    📈 X (Twitter) Top Accounts · All Categories · All Genders
    
    Data date: 2026-09-21 (Page 1/10)
    200 accounts ranked (20 shown on this page)
    
    💡 Note: the ranking is updated at 9:00 AM daily for the previous day and may differ from realtime data
    
    📐 Influence score: weighted evaluation of followers, engagement and impressions, out of 100
    
    | Rank | Account        | Biography                  | Country | Industry              | Score | Daily Δ | X Followers | Other Platforms | Tags |
    | :--: | -------------- | -------------------- | :-----: | --------------------- | :---: | :-----: | :---------: | --------------- | ---- |
    | 🥇 1 | Name (link)    |  biography    |   US    | Tech & Software       | 99/100 | +1.25% | 2.2亿+      | —               | Tags |
    | 🥈 2 | Name (link)    | biography       |   US    | Entertainment & Culture | 97/100 | +0.88% | 3,100w+   | YouTube 4亿+    | —    |
    |  …   | …              | …                    |    …    | …                     |   …   |    …    |      …      | …               | …    |
    
    ⚡ More actions
    ⏺️ This ranking has 200 items in total. Continue to page 2?
    
    📬 Subscription
    1️⃣ Subscribe to the daily X (Twitter) ranking push?
    2️⃣ Filters supported: gender (all / male / female) and 32 industry categories
    
    ---
    
    ## Use Cases
    
    | Scenario                    | Role                        | Example question                              | Benefit                              |
    | --------------------------- | --------------------------- | --------------------------------------------- | ------------------------------------ |
    | Find benchmark accounts     | Creators / solo operators   | "Which tech accounts perform best on X?"      | Identify niche leaders quickly       |
    | Evaluate creator candidates | Brands / advertisers        | "Top 20 female beauty creators?"              | Batch screening for better decisions |
    | Monitor competitors         | MCN / cross-border ops      | "Any new faces on page 2 of the pet ranking?" | Track market shifts in time          |
    | Industry analysis reports   | Analysts / consultants      | "HTML report for the finance ranking"         | One-click visual report for sharing  |
    | Track ranking changes       | Ops teams                   | "Send me the tech ranking every day"          | Automated ranking intelligence       |
    
    ---
    
    ## Data Notes
    
    ### Update Time & Lookback
    
    | Rule        | Description                                                    |
    | ----------- | -------------------------------------------------------------- |
    | Update time | 9:00 AM daily for the previous day's ranking                   |
    | Lookback    | Past 7 days                                                    |
    | Empty data  | Automatically falls back to the nearest available date         |
    
    ### Supported Filters
    
    - **Gender (3)**: all, male, female
    - **Industry (32)**: 全部行业 (all), 商业创业, 汽车出行, 设计创意, 航空领域, 电商零售, 教育培训, 工程运营, 娱乐文化, 环境能源, 家庭育儿, 时尚美妆, 金融投资, 美食饮品, 游戏电竞, 健康医疗, 牧场马术, 宗教信仰, 科学学术, 体育健身, 科技软件, 旅行户外, 视觉艺术, 健康生活, 居家手工, 人力职场, 公益平权, 法律法务, 市场营销, 音乐领域, 萌宠动物, 政治新闻 (category values are passed to the API in Chinese)
    
    ### Data Freshness
    
    Data is not realtime; account metrics reflect the collection moment and may differ from live values.
    
    ---
    
  • README.md 6.5 KB
    # X (Twitter) 热门账号榜 / x-top-account
    
    **中文** | [English](README.en.md)
    
    ---
    
    ## 简介
    
    帮你快速发现 X (Twitter) 平台最具影响力的账号,掌握全球头部创作者格局。
    
    **核心价值**
    基于每日 X 平台 TOP200 影响力账号的粉丝、涨幅、跨平台数据,帮你解决对标账号、海外投放、竞品监控、行业洞察四大核心问题。
    
    **适用对象**
    
    - 🌏 出海内容创作者 — 了解同赛道头部账号表现,寻找对标和学习对象
    - 🏢 品牌方/海外投放 — 高效筛选优质达人,评估跨平台合作价值
    - 📦 MCN 机构/跨境运营 — 掌握竞品动态,制定运营策略
    - 📊 行业分析师 — 获取数据洞察,生成分析报告
    
    ---
    
    ## 功能特性
    
    ### 核心功能
    
    - **排名查询**:查询 X 平台每日影响力账号榜,每页 20 条、共 10 页 200 条,支持翻页浏览
    - **筛选过滤**:支持性别(全部/男/女)与 32 个行业分类精准查询,支持模糊词匹配(如"宠物"自动映射萌宠动物)
    - **影响力评分**:结合粉丝数、互动量、曝光数等加权综合评估,满分 100 分
    - **HTML 报告生成**:生成 X 平台风格的可视化 HTML 文件,账号名可点击跳转 X 主页,支持一键导出 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` 后使用本技能。
    - 在提供密钥前,请先确认密钥来源、可用范围、有效期及是否支持重置/撤销。
    - 禁止在代码、提示词、日志或输出文件中硬编码/明文暴露密钥。
    
    ---
    
    ## 使用指南
    
    直接用自然语言描述你的需求,无需记忆任何命令格式。
    
    ### 常用说法速查
    
    | 意图       | 示例话术                                   | 效果                          |
    | ---------- | ------------------------------------------ | ----------------------------- |
    | 查最新榜   | "给我最新的 Twitter 全品类日榜"            | 返回最新日期第 1 页 20 条     |
    | 查行业榜   | "宠物类 Twitter 账号排行怎么样?"          | 返回萌宠动物行业最新榜单      |
    | 查性别榜   | "看看美妆类女博主的 X 榜单"                | 返回时尚美妆 + 女性筛选榜单   |
    | 指定日期   | "给我 2026 年 9 月 20 日的 Twitter 榜单"    | 返回指定日期榜单              |
    | 翻页       | "继续看第 2 页"                            | 返回第 2 页 20 条             |
    | 下载报告   | "帮我生成这次榜单的 HTML 报告"             | 生成可视化 HTML 文件并交付    |
    | 订阅推送   | "我想每天收到宠物类 X 榜单更新"            | 创建定时自动推送任务          |
    
    ### 输出示例
    
    📈 X (Twitter) 热门账号榜 · 全部行业 · 全部
    
    数据日期:2026-09-21(第 1/10 页)
    共 200 个账号上榜(本页展示 20 条)
    
    💡 榜单说明:每日早上 9:00 更新前一天榜单,与实时数据存在差异
    
    📐 影响力评分:结合粉丝数、互动量、曝光数等加权综合评估,满分 100
    
    | 排名 | 账号名           | 账号简介             | 国家/地区 | 主行业                | 影响力评分 | 日涨幅  | X粉丝数 | 其他平台粉丝数 | 专题标签 |
    | :--: | ---------------- | -------------------- | :-------: | --------------------- | :--------: | :-----: | :-----: | -------------- | -------- |
    | 🥇 1 | 账号名(可点击) |  简介          |   美国    | Tech & Software       |   99/100   | +1.25%  | 2.2亿+  | —              | 标签     |
    | 🥈 2 | 账号名(可点击) | 简介                |   美国    | Entertainment & Culture |  97/100  | +0.88%  | 3,100w+ | YouTube 4亿+   | —        |
    |  …   | …                | …                    |     …     | …                     |     …      |    …    |    …    | …              | …        |
    
    ⚡ 更多操作
    本次榜单完整共 200 条数据,是否需要继续查看第 2 页?
    
    📬 订阅服务
    1️⃣ 是否需要订阅每日 X(Twitter) 账号最新排名?
    2️⃣ 支持您按照性别(全部/男/女)与 32 个行业分类筛选项订阅
    
    ---
    
    ## 使用场景
    
    | 场景                 | 角色                  | 示例问法                                  | 收益                               |
    | -------------------- | --------------------- | ----------------------------------------- | ---------------------------------- |
    | 寻找赛道标杆账号     | 出海创作者 / 个体运营 | "科技类 Twitter 账号哪些做得好?"         | 快速找到行业头部,明确内容方向     |
    | 评估达人合作候选人   | 品牌方 / 海外投放     | "美妆类女博主 TOP20 有哪些表现亮眼?"     | 批量筛选,提升投放决策效率         |
    | 监控竞品赛道动态     | MCN / 跨境运营团队    | "宠物榜第 2 页有哪些新面孔?"             | 实时掌握竞争格局,快速响应市场变化 |
    | 生成行业分析报告     | 行业分析师 / 咨询顾问 | "帮我生成金融投资行业榜单的 HTML 报告"    | 一键生成可视化 HTML,方便汇报分享  |
    | 定期追踪账号排名变化 | 运营团队              | "我想每天收到科技类 X 榜单更新"           | 订阅推送,自动化榜单情报获取       |
    
    ---
    
    ## 重要数据说明
    
    ### 榜单更新时间与数据回溯
    
    | 规则     | 说明                              |
    | -------- | --------------------------------- |
    | 更新时间 | 每日早上 9:00 更新昨日榜单      |
    | 回溯范围 | 过去 7 天                         |
    | 空数据   | 目标日期无数据时,自动回退最近可用日期 |
    
    ### 支持筛选项
    
    - **性别(3 项)**:全部、男、女
    - **行业分类(32 类)**:全部行业、商业创业、汽车出行、设计创意、航空领域、电商零售、教育培训、工程运营、娱乐文化、环境能源、家庭育儿、时尚美妆、金融投资、美食饮品、游戏电竞、健康医疗、牧场马术、宗教信仰、科学学术、体育健身、科技软件、旅行户外、视觉艺术、健康生活、居家手工、人力职场、公益平权、法律法务、市场营销、音乐领域、萌宠动物、政治新闻
    
    
  • SKILL.md 12.6 KB
    ---
    name: x-top-account
    description: X(Twitter)每日最具影响力账号榜单追踪分析工具;每日早上9:00更新前一天榜单,最多回溯7天;支持性别(男/女/全部)与32个行业分类筛选、分页翻页、HTML可视化报告导出与定时订阅推送;当用户需要查询X/Twitter账号排名、热门账号榜、分行业/分性别榜单、下载榜单报告或订阅推送时使用。触发词:X榜单、Twitter榜单、推特账号排名、X热门账号、Twitter影响力榜、推特大V排行。
    dependency: {}
    ---
    
    # X (Twitter) 热门账号榜
    
    ## 1. 简介
    
    X (Twitter) 每日最具影响力账号榜单追踪分析工具 -- 基于红狐数据 API,提供 X 平台全行业 / 分行业 / 分性别的每日影响力账号榜单查询,支持排名查询、筛选过滤、分页翻页、HTML 可视化报告下载与定时订阅推送。
    
    **适用对象**:出海内容创作者、品牌方 / 海外投放人员、MCN 机构 / 跨境运营团队、行业分析师 / 咨询从业者。
    
    ---
    
    ## 2. 功能特性
    
    **核心功能**:
    
    - 排名查询 -- 查每日 TOP 账号榜(每页 20 条,共 10 页 200 条)
    - 筛选过滤 -- 按性别与 32 个行业分类精准筛选,支持自然语言模糊匹配
    - 分页翻页 -- 支持指定页码查询,对话内逐页浏览
    - 报告下载 -- 生成 X 平台风格 HTML 报告,支持一键导出 PDF / 高清图片
    - 定时订阅 -- 设置每日定时推送,支持按性别 / 行业组合订阅
    
    **特色亮点**:
    
    - 每日早上 9:00 更新前一天榜单,最多回溯 7 天
    - 影响力评分:结合粉丝数、互动量、曝光数等加权综合评估,满分 100
    - 行业模糊匹配:支持自然语言输入(如 "宠物" 自动映射到 "萌宠动物")
    - 多维数据:国家/地区、主行业、日涨幅、X 粉丝数、其他平台粉丝数、专题标签一览无余
    
    ---
    
    ## 3. 一键安装
    
    ### 鉴权
    
    #### 获取 API Key
    
    请前往 [红狐hub](https://redfox.hk/settings/api-keys?source=github) 获取API KEY
    
    #### 配置 API Key
    
    方案1: 以OpenClaw为例,将REDFOX_API_KEY添加到~/.openclaw/openclaw.json中
    
    ```bash
    { "env": { "REDFOX_API_KEY": "ak_xxxx..." } }
    ```
    
    方案2: 终端配置:export REDFOX_API_KEY="ak_xxxx..."
    
    ```bash
    export REDFOX_API_KEY="ak_xxxx..."
    ```
    
    ### 依赖安装
    
    无需安装第三方依赖,使用 Python 标准库即可运行。
    
    ---
    
    ## 4. 使用指南
    
    ### 基础使用
    
    **查询榜单数据(默认第 1 页 20 条)并生成 HTML 报告**:
    
    ```bash
    python scripts/fetch_rank.py --query "用户原始问题" --html
    ```
    
    脚本会自动解析:
    - **日期**:未明确则取最新可用日期(每日 9:00 更新,9 点后为昨日,9 点前为前日)
    - **性别**:识别 男/女(如 "女博主" → female),未明确则 all
    - **行业**:模糊匹配 32 个行业(如 "宠物" → "萌宠动物"),接口 category 传行业中文名,未明确则 all;skill 内部不暴露英文分类值
    - **页码**:识别 "第2页" 等表达,未明确则第 1 页
    
    **翻页查询**:
    
    ```bash
    python scripts/fetch_rank.py --query "用户原始问题" --page 2 --html
    ```
    
    **显式指定筛选条件**(优先级高于 --query 解析结果):
    
    ```bash
    python scripts/fetch_rank.py --date 2026-09-20 --gender female --category "萌宠动物" --html
    ```
    
    > 重要:HTML 报告展示的数据条数必须与对话中展示的数量保持一致(每页 20 条)。使用 `deliver_attachments` 交付 HTML 文件。
    
    ### 高级使用
    
    **更新时间与回溯范围(必须输出给用户)**:
    
    - 榜单每日早上 **9:00** 更新**前一天**数据
    - 最多回溯**过去 7 天**
    
    **时间边界处理(必须严格遵守)**:
    - 查询当日及未来日期:回复「非常抱歉🙏,我们最新的是昨日的数据,将为您提供最接近您需求的昨日热榜。」
    - 查询时间早于回溯日期:回复「非常抱歉🙏,目前榜单最多支持回溯「过去7天」,我将为您查询最接近您需求的时间范围~」
    - 目标日期接口返回空数据:脚本自动回退到最近可用日期并输出 `[WARN]` 提示,需转述给用户
    
    **订阅服务**:
    
    用户确认订阅后,使用 `automation_update` 工具创建自动化任务:
    - 每日订阅:`FREQ=DAILY;BYHOUR=9;BYMINUTE=30`(数据 9:00 更新后推送)
    
    automation prompt 示例:`查询X(Twitter)最新热门账号榜(行业:全部行业,性别:全部),生成报告并推送给用户`
    
    **订阅询问时必须罗列全部筛选项**(见「输出格式」订阅服务模板):
    - 性别:全部(all) / 男(male) / 女(female)
    - 行业分类:32 个行业中文名全量罗列,完整枚举见 [references/category_map.md](references/category_map.md)
    
    ### 常用指令速查
    
    | 用户意图 | 典型触发词 | 对应操作 |
    | -------- | ---------- | -------- |
    | 排名查询 | X榜单、Twitter日榜、推特热门账号、影响力排行 | 调用脚本查询并格式化输出 |
    | 筛选查询 | 宠物类/科技类/女博主...Twitter排名 | 调用脚本并按行业/性别筛选 |
    | 翻页 | 第2页、下一页、继续看 | 加 --page 参数重新查询 |
    | 报告下载 | 下载报告、导出榜单、生成报告 | 运行脚本加 --html 生成并交付 |
    
    ### 输出格式
    
    **Markdown 表格模板**:
    
    ```
    📈 X (Twitter) 热门账号榜 · {category_label} · {gender_label}
    数据日期:{rankDate}(第 {pageNum}/{pages} 页)
    共 {total} 个账号上榜(本页展示 20 条)
    
    💡 榜单说明:每日早上 9:00 更新前一天榜单,与实时数据存在差异
    📐 影响力评分:结合粉丝数、互动量、曝光数等加权综合评估,满分 100
    
    | 排名 | 账号名 | 账号简介 | 国家/地区 | 主行业 | 影响力评分 | 日涨幅 | X粉丝数 | 其他平台粉丝数 | 专题标签 |
    |:---:|--------|--------|:---:|--------|:---:|:---:|:---:|--------|--------|
    | 🥇 1 | [Elon Musk](profile_url)<br>*Tech Entrepreneur and CEO* | biography 简介(前 60 字) | 美国 | Tech & Software | 99/100 | +1.25% | 2.2亿+ | — | 账号标签 |
    | 🥈 2 | [MrBeast](profile_url)<br>*Creator & Philanthropist* | biography 简介(前 60 字) | 美国 | Entertainment & Culture | 97/100 | +0.88% | 3,100w+ | YouTube 4亿+ | — |
    | 🥉 3 | [iJustine](profile_url)<br>*Tech Vlogger* | biography 简介(前 60 字) | 美国 | Tech & Software | 93/100 | +0.69% | 180w+ | YouTube 7,100w+ / TikTok 1,600w+ | Women in Tech / STEM |
    ```
    
    **字段展示规则**:
    - 账号名:Markdown 链接 `[fullName](profileUrl)` + `<br>` + 头衔(`title`,斜体),头衔不换列、不省略;1-3 名加 🥇🥈🥉
    - 账号简介:仅 `biography`(过长时截取前 60 字),头衔不放入本列
    - 影响力评分:xScore 四舍五入取整,格式 `99/100`
    - X粉丝数:≥1亿 显示 `x.x亿+`,≥1万 显示 `x,xxxw+`
    - 其他平台粉丝数:逐条展示 `otherNetworks[].network` 平台名 + `followersFmt`(如 `YouTube 400w+`;字段名是 `network`,不是 `platform`),多个平台用 ` / ` 连接,无则 `—`
    - 专题标签:取专题话题 topics,无则取公益标签 cause,均无则 `—`
    - 完整性:表格 10 列全部输出,不得为压缩列宽省略任何字段或整列;HTML 报告与对话表格版式保持一致(头衔在账号名下方,简介列仅 biography)
    
    输出完榜单后追加:
    
    ```
    总结榜单构成
    {AI 对榜单数据做一些分析:头部集中度、行业分布、国家分布、涨粉亮点等}
    
    ⚡ 更多操作
    • 点击下方下载 HTML 报告文件,可在浏览器中打开查看,支持一键导出 PDF / 高清图片
    • 本次榜单完整共 {total} 条数据,是否需要继续查看第 {pageNum+1} 页?
    
    📬 订阅服务
    1️⃣ 是否需要订阅每日 X(Twitter) 账号最新排名,订阅后定时推送给您(每日早上 9:00 更新前一天榜单)。
    2️⃣ 支持您按照以下筛选项订阅:
       • 性别:全部 / 男 / 女
       • 行业分类:全部行业、商业创业、汽车出行、设计创意、航空领域、电商零售、教育培训、工程运营、娱乐文化、环境能源、家庭育儿、时尚美妆、金融投资、美食饮品、游戏电竞、健康医疗、牧场马术、宗教信仰、科学学术、体育健身、科技软件、旅行户外、视觉艺术、健康生活、居家手工、人力职场、公益平权、法律法务、市场营销、音乐领域、萌宠动物、政治新闻
    ```
    
    ---
    
    ## 5. 使用场景
    
    | 用户分层 | 核心痛点 | 使用方式 |
    | -------- | -------- | -------- |
    | 出海内容创作者 | 不知道同赛道头部账号是谁、无从对标 | 查询 "科技类 Twitter 榜单",获取对标参考 |
    | 品牌方 / 海外投放 | 找海外达人效率低、不了解账号跨平台影响力 | 查询 "美妆类女博主榜单",评估投放候选 |
    | MCN / 跨境运营团队 | 竞品账号情报获取难 | 查询 "宠物榜第2页",逐页监控市场 |
    | 行业分析师 | 数据维度单一、缺乏可视化报告 | 生成 "金融投资行业榜单 HTML 报告" |
    
    **预期收益**:快速掌握 X 平台头部账号格局、识别高增长账号、降低海外投放决策成本。
    
    ---
    
    ## 6. 项目架构
    
    ### 目录结构
    
    ```
    x-top-account/
    ├── SKILL.md                          # 本文件
    ├── scripts/
    │   ├── fetch_rank.py                 # 查询榜单数据(解析/翻页/容错回退)
    │   └── generate_report.py            # 生成 X 风格 HTML 报告(导出 PDF/图片)
    ├── assets/
    │   └── category_config.json          # 更新规则 + 性别/行业枚举与关键词映射
    ├── output/                           # HTML 报告输出目录(运行时自动创建)
    └── references/
        ├── category_map.md               # 行业映射表与匹配规则
        └── api_docs.md                   # API 接口详细文档(技术参考)
    ```
    
    ### 核心模块说明
    
    - **fetch_rank.py**:接收用户查询参数,调用红狐 API 获取榜单数据,自动解析日期、性别、行业与页码,目标日期无数据时自动回退最近可用日期,输出 JSON 数据文件;加 `--html` 自动调用报告生成。
    - **generate_report.py**:读取 JSON 数据生成 X 平台风格(纯白底 + X 蓝)HTML 报告,报告标题格式 `X(Twitter)·{行业}·热门{性别}账号榜`(行业/性别为 all 时省略对应字段),默认保存到 skill 目录下 `output/`(自动创建),文件名格式 `X账号榜_{性别}_{分类}_{日期}.html`(性别/分类为 all 时展示为全部性别/全部分类,如 `X账号榜_全部性别_全部分类_2026-09-21.html`)。列版式与对话表格一致:账号名列展示头像 + 账号名(可点击跳转 X 主页)+ 头衔(账号名下方,超长省略号、悬停显示全文),账号简介列仅 biography(悬停显示全文),其他平台粉丝数带平台名且可点击跳转对应主页;内置导出 PDF / 高清图片按钮,生成后自动打开浏览器。
    
    ### 资源索引
    
    | 文件 | 用途 |
    | ---- | ---- |
    | [scripts/fetch_rank.py](scripts/fetch_rank.py) | 查询榜单数据 |
    | [scripts/generate_report.py](scripts/generate_report.py) | 生成 HTML 可视化报告 |
    | [references/category_map.md](references/category_map.md) | 行业映射表与匹配规则 |
    | [references/api_docs.md](references/api_docs.md) | API 接口详细文档(技术参考) |
    
    ---
    
    ## 7. 常见问答
    
    ### 安装
    
    **Q: 需要安装什么依赖?**
    A: 无需安装第三方依赖,使用 Python 标准库即可运行。
    
    **Q: 如何配置 API Key?**
    A: 请前往 [红狐hub](https://redfox.hk/settings/api-keys?source=github) 获取 API KEY,然后通过环境变量 `REDFOX_API_KEY` 配置。
    
    ### 使用
    
    **Q: 榜单数据什么时候更新?**
    A: 每日早上 9:00 更新前一天榜单。当前时间未到 9:00 时,脚本会自动取前天数据。
    
    **Q: 支持哪些筛选?**
    A: 性别 3 项(全部/男/女)+ 行业 32 类,完整列表见 [references/category_map.md](references/category_map.md)。
    
    **Q: 数据回溯范围?**
    A: 最多回溯过去 7 天;目标日期无数据时自动回退最近可用日期并提示。
    
    **Q: 行业识别失败怎么办?**
    A: 无法识别时降级为全部行业,并列出完整行业列表供用户选择。
    
    **Q: 每页多少条?如何翻页?**
    A: 每页固定 20 条,共 10 页 200 条;对话中询问用户是否查看下一页,使用 `--page N` 翻页。
    
    ### 故障排除
    
    **Q: HTML 报告生成失败?**
    A: 确保 workspace 有写权限,且 JSON 数据文件路径正确。
    
    **Q: 数据不一致?**
    A: 对话展示多少条(每页 20 条),HTML 报告就展示多少条,两者必须一致。翻页后需重新生成对应页报告。
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related