
Douyin Works Crawler
- 248 installs
- 316 repo stars
- Updated August 4, 2026
- redfox-data/redfox-community
Use douyin-works-crawler for development tasks
About
douyin-works-crawler: A skill for development. This provides functionality for development workflows.
- douyin-works-crawler
Douyin Works Crawler by the numbers
- 248 all-time installs (skills.sh)
- +17 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #1,549 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/redfox-data/redfox-community --skill douyin-works-crawlerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 248 |
|---|---|
| repo stars | ★ 316 |
| Last updated | August 4, 2026 |
| Repository | redfox-data/redfox-community ↗ |
What it does
Use douyin-works-crawler for development tasks
Files
抖音作品爬取
输入抖音名称或ID,一键获取账号基础信息 + 近期作品内容
---
简介
抖音作品爬取是一款专为抖音内容分析打造的智能工具,帮助用户快速获取任意抖音账号的基础信息和近期作品数据。
通过简单的账号名称或抖音号输入,你可以:
- 📊 获取账号基础信息(粉丝数、获赞、作品总数、红狐指数等)
- 📋 查看近期作品列表(最多50条,含互动数据和作品链接)
- 🔍 发现互动TOP3作品,获取值得学习的内容分析
- 📥 未收录账号支持一键提交收录,30分钟后自动同步
适用于品牌方、MCN机构、内容运营、自媒体从业者等需要分析抖音账号表现的场景。
---
功能特性
🎯 核心功能
- 📊 账号信息查询:输入抖音昵称或抖音号,一键获取账号基础数据(粉丝数、获赞、作品总数、红狐指数等)
- 📋 近期作品爬取:自动获取近期作品列表(最多50条),包含点赞、评论、分享、互动数及作品链接
- 🔍 数据亮点分析:互动量TOP3作品分析 + 账号特征分析(更新频率、互动表现、爆款特征)
✨ 特色亮点
- ⚡ 智能识别:自动判断输入类型(昵称/抖音号),无需手动切换查询模式
- 📥 账号收录:未收录账号支持一键提交收录,30分钟后自动同步数据
- 🔗 直达链接:昵称跳转账号主页,作品列表跳转视频页面
- 🔒 安全可靠:API 接入方式,无需登录抖音账号
---
一键安装
前置条件
- Python 3.6+
- 红狐数据API密钥(格式
ak_xxx)
安装方式
方式一:直接使用(推荐)
1. 确保项目文件已下载到本地 2. 配置环境变量:
# macOS/Linux
export REDFOX_API_KEY=你的API密钥值
# Windows PowerShell
$env:REDFOX_API_KEY="你的API密钥值"3. 运行查询:
python scripts/douyin_works_fetcher.py --account "抖音名称或抖音号"方式二:在 Coze/Dify 等平台配置
1. 将技能文件夹上传至平台 2. 在环境变量中配置 REDFOX_API_KEY 3. 配置触发词,即可通过对话调用
环境变量配置
| 变量名 | 必填 | 说明 |
|---|---|---|
REDFOX_API_KEY | 是 | 红狐数据API密钥(格式 ak_xxx) |
---
使用指南
基础使用
1. 查询账号作品
告诉助手你想查询的抖音账号:
用户:爬取"周幺姑家常菜"的抖音作品
>
助手:已为您查询到「周幺姑家常菜」的账号数据,粉丝547.1w,近期47条作品...
2. 精准查询(推荐)
使用抖音号进行精准查询,避免昵称模糊匹配:
用户:帮我查询抖音号 cdjjc028 的作品
>
助手:已精准匹配到「周幺姑家常菜」的账号数据...
3. 账号收录
当账号未被收录时,回复抖音号即可提交收录:
用户:帮我查询"xxx"的作品
>
助手:未查询到当前账号的相关信息,可提交当前抖音账号进行账号收录。1. 回复抖音号...2. 下次再说;
>
用户:1212_1234
>
助手:已提交账号收录请求,系统正在同步数据,约30分钟后可再次查询。
高级使用
4. 导出JSON格式
需要结构化数据时,可指定JSON输出:
python scripts/douyin_works_fetcher.py --account "抖音号" --output json5. 命令行直接提交收录
python scripts/douyin_works_fetcher.py --account "任意" --sync "抖音号"命令速查
| 命令 | 功能 |
|---|---|
爬取抖音作品 [名称/抖音号] | 查询账号作品数据 |
抖音作品列表 [名称/抖音号] | 获取近期作品列表 |
抖音内容采集 [名称/抖音号] | 采集账号内容 |
导出抖音作品 [名称/抖音号] | 导出作品数据 |
| 回复抖音号 | 提交账号收录(未命中时) |
---
使用场景
场景一:品牌方竞品监测
角色:品牌营销经理
需求:监测竞品抖音账号的内容表现和互动数据
使用方式: 1. 输入竞品账号的抖音号进行查询 2. 查看近期作品列表和互动数据 3. 分析互动TOP3作品的内容特征
预期收益:及时掌握竞品内容动态,优化自身内容策略
---
场景二:MCN 机构达人评估
角色:MCN 运营人员
需求:评估达人账号的数据表现和内容方向
使用方式: 1. 查询目标达人的账号基础信息(粉丝数、获赞、红狐指数) 2. 分析近期作品的互动表现 3. 查看账号特征分析,了解更新频率和内容方向
预期收益:快速评估达人价值,辅助签约决策
---
场景三:自媒体内容优化
角色:抖音内容创作者
需求:学习同领域头部账号的爆款内容特征
使用方式: 1. 查询同领域头部账号的作品数据 2. 查看互动TOP3作品的分析 3. 学习爆款内容值得借鉴的点
预期收益:找到内容优化方向,提升账号互动表现
---
场景四:数据分析报告
角色:数据分析师
需求:批量获取抖音账号的结构化数据用于分析
使用方式: 1. 使用 --output json 参数导出结构化数据 2. 批量查询多个账号 3. 结合其他数据进行综合分析
预期收益:高效获取数据,支撑分析报告输出
---
项目架构
目录结构
douyin-works-crawler/
├── scripts/
│ └── douyin_works_fetcher.py # 核心脚本(API调用+数据格式化)
├── references/
│ └── core_workflow.md # 核心技能逻辑(接口规范、输出模板、处理规则)
├── CONFIG.json # 技能配置文件
└── SKILL.md # 技能说明文档技术栈
| 项目 | 说明 |
|---|---|
| 运行环境 | Python 3.6+ |
| 数据来源 | 红狐数据API |
| 认证方式 | API Key(X-API-KEY请求头) |
| 输出格式 | Markdown / JSON |
核心模块说明
- DouyinWorksFetcher:核心类,封装查询和收录两大功能
query_account():查询账号信息和作品列表sync_account():提交账号收录请求format_markdown()/format_json():输出格式化
📌 完整的接口规范、输出模板、处理规则等核心逻辑详见 [references/core_workflow.md](references/core_workflow.md),Agent 执行时必须遵循该文件中的所有规则。
---
常见问答
安装相关问题
Q1: 运行时提示"未设置环境变量 REDFOX_API_KEY"怎么办?
A: 请先配置环境变量:
# macOS/Linux
export REDFOX_API_KEY=你的API密钥值
# Windows PowerShell
$env:REDFOX_API_KEY="你的API密钥值"Q2: 红狐数据API密钥如何获取?
A: 前往红狐平台注册并申请API密钥,格式为 ak_xxx。
---
使用相关问题
Q3: 用昵称查询返回的不是我要找的账号怎么办?
A: 抖音昵称不唯一,建议使用抖音号进行精准查询。抖音号在抖音APP → 目标账号主页 → 昵称下方查看。
Q4: 为什么有些账号查不到?
A: 可能该账号尚未被红狐平台收录。查询未命中时会提示账号收录,回复抖音号即可提交收录,约30分钟后可再次查询。
Q5: 作品列表最多显示多少条?
A: 近期作品数据最多50条,按发布时间倒序排列。awemeCount 字段为账号历史作品总数,作品列表中的数量可能小于该值。
---
故障排除
Q6: API调用报错"积分不足"怎么办?
A: 红狐API按调用次数计费,请前往红狐平台充值积分。
Q7: 查询超时怎么办?
A: 请检查网络连接是否正常,脚本默认超时时间为30秒。如持续超时,可稍后重试。
---
版本信息
- 当前版本: v2.3
- v2.3更新: 新增账号收录功能;未查询到账号时输出收录提示;新增数据亮点模块(互动量TOP3+账号特征分析);数据来源描述统一为"红狐数据API"
- v2.2更新: 数字格式规范(万→w,≥1亿用亿,<1万千分位);链接列格式固定为
[链接](url)/- - v2.1更新: 接口新增url字段,支持作品直达链接输出
- v2.0更新: 切换至
/dyData/queryUserWithWorks接口,支持近期作品数据爬取 - v1.0更新: 初始版本
Douyin Works Crawler / douyin-works-crawler
---
Overview
A Douyin content data retrieval tool. Enter a Douyin nickname or ID to instantly fetch account basic info and recent works (up to 50 items), including engagement data and direct video links—plus a TOP 3 engagement analysis and account feature summary to help you quickly understand the target account's content performance.
Core Value
- One-click works retrieval: Enter a nickname or Douyin ID to automatically fetch account basic info (followers, total likes, total works, RedFox Index) and recent work lists.
- Auto data highlight analysis: TOP 3 engagement works analysis + account feature summary (posting frequency, content direction, engagement trends, viral patterns)—quickly identify content worth learning from.
- Direct work links: Each work comes with a direct link—click to jump to the original video.
- One-click unlisted account submission: For accounts not yet indexed, reply with the Douyin ID to submit for indexing—data auto-syncs in about 30 minutes.
Intended Users
- 🏢 Brands / marketing managers — Monitor competitor Douyin account content performance and engagement data.
- 🛍️ MCN / operations staff — Quickly evaluate creator account data performance and content direction.
- 📝 Douyin content creators — Learn viral content patterns from top accounts in your niche.
- 📊 Data analysts — Batch-fetch structured data for analysis reports.
---
Features
Core Capabilities
- Account info query: Enter a Douyin nickname or ID to instantly fetch account basic data (followers, total likes, total works, RedFox Index, etc.).
- Recent works retrieval: Automatically fetch recent works (up to 50 items), including likes, comments, shares, engagement counts, and direct work links.
- Data highlight analysis: Output TOP 3 engagement works analysis + account feature analysis (posting frequency, engagement trends, viral patterns).
Highlights
- Smart recognition: Automatically detects input type (nickname/ID)—Chinese input uses nickname search, non-Chinese uses precise ID search.
- Account indexing: Unlisted accounts support one-click indexing submission—data auto-syncs in about 30 minutes.
- Direct links: Nickname links to account homepage; each work provides a direct video link.
- Safe & secure: Data service-based access—no Douyin account login required.
---
API Key Acquisition & Security
- This skill requires the environment variable:
REDFOX_API_KEY. REDFOX_API_KEYis issued by RedFoxHub (https://redfox.hk)- Register at RedFoxHub to obtain
REDFOX_API_KEY. - Configure
REDFOX_API_KEYon your device before using this skill. - Before providing your key, confirm its source, scope, validity period, and whether it can be reset or revoked.
- Do not hard-code or expose keys in plain text in code, prompts, logs, or output files.
---
Usage Guide
Simply describe your query needs in natural language—no commands to memorize.
Quick Reference
| Intent | Example phrase | Result |
|---|---|---|
| Query account works | "Crawl Douyin works for 周幺姑家常菜" | Fetch account basic info + recent work list + data highlight analysis |
| Precise query | "Query works for Douyin ID cdjjc028" | Precise ID match, avoiding nickname ambiguity |
| Submit account indexing | "My account can't be found, Douyin ID is 1212_1234" | Submit indexing request; query again in ~30 minutes |
| Export data | "Export works data for 周幺姑家常菜" | Get structured works data |
Output Example
After querying, you will receive the following structured results:
Account Basic Info: Nickname (clickable to homepage), Douyin ID, region, followers, total likes, total works, RedFox Index
Recent Works List (up to 50 items, reverse chronological):
| # | Publish Time | Title | Likes | Comments | Shares | Engagement | Link | | … | … | … | … | … | … | … | Clickable to original video |
Data Highlights: TOP 3 engagement works analysis + Account features (posting frequency, content direction, engagement trends, viral patterns)
---
(When no data is found, the system guides you to reply with a Douyin ID for indexing—data syncs in ~30 minutes.)
---
Use Cases
| Scenario | Role | Example question | Benefit |
|---|---|---|---|
| Brand competitor monitoring | Brand marketing manager | "Check the works data and engagement of this competitor Douyin account for me" | Stay on top of competitor content trends; optimize your own strategy |
| MCN creator evaluation | MCN operations staff | "Show me this creator's followers, likes, and recent works data" | Quickly evaluate creator value; support signing decisions |
| Content optimization learning | Douyin creator | "Check the works of top accounts in my niche and analyze viral patterns" | Find content optimization directions; boost account engagement |
| Data analysis reports | Data analyst | "Export works data for these Douyin accounts for analysis" | Efficiently fetch structured data to support analysis reports |
---
Important Data Notes
- The work list shows recent works only—up to 50 items in reverse chronological order, not the account's full historical works.
- Number formatting: ≥10k displays as
x.xw(e.g., 3.2w), ≥100M displays asx.x亿; <10k uses comma separators. - Douyin nicknames are not unique; nickname queries may return fuzzy matches—use Douyin ID for precise lookup.
- Unlisted accounts can be submitted for indexing; data auto-syncs in about 30 minutes.
- All data comes exclusively from the data platform; no third-party supplementation or estimation.
---
抖音作品爬取 / douyin-works-crawler
---
简介
抖音作品数据获取工具,输入抖音昵称或抖音号,一键获取账号基础信息与近期作品内容列表(最多 50 条),含互动数据和作品直达链接,并提供互动 TOP3 分析与账号特征总结,帮助用户快速掌握目标账号的内容表现。
核心价值
- 一键获取作品数据:输入昵称或抖音号,自动获取账号粉丝数、获赞、作品总数等基础信息及近期作品列表。
- 数据亮点自动分析:互动量 TOP3 作品分析 + 账号特征总结(更新频率、内容方向、互动表现、爆款特征),快速发现值得学习的内容。
- 作品直达链接:每条作品提供直达链接,点击即可跳转查看原视频。
- 未收录账号一键提交:查询不到的账号,回复抖音号即可提交收录,约 30 分钟后自动同步数据。
适用对象
- 🏢 品牌方 / 营销经理 — 监测竞品抖音账号的内容表现和互动数据。
- 🛍️ MCN / 运营人员 — 快速评估达人账号的数据表现和内容方向。
- 📝 抖音内容创作者 — 学习同领域头部账号的爆款内容特征。
- 📊 数据分析师 — 批量获取结构化数据用于分析报告。
---
功能特性
核心功能
- 账号信息查询:输入抖音昵称或抖音号,一键获取账号基础数据(粉丝数、获赞、作品总数、红狐指数等)。
- 近期作品获取:自动获取近期作品列表(最多 50 条),包含点赞、评论、分享、互动数及作品直达链接。
- 数据亮点分析:输出互动量 TOP3 作品分析 + 账号特征分析(更新频率、互动表现、爆款特征)。
特色亮点
- 智能识别:自动判断输入类型(昵称/抖音号),含中文走昵称查询,非中文走抖音号精准查询。
- 账号收录:未收录账号支持一键提交收录,约 30 分钟后自动同步数据。
- 直达链接:昵称可跳转账号主页,每条作品提供直达链接。
- 安全可靠:通过数据服务接入,无需登录抖音账号。
---
密钥获取与安全说明
- 本技能需要使用环境变量:
REDFOX_API_KEY。 REDFOX_API_KEY由 红狐 hub (https://redfox.hk)提供。- 请前往 红狐 hub 注册账号,获取
REDFOX_API_KEY。 - 配置设备环境变量
REDFOX_API_KEY后使用本技能。 - 在提供密钥前,请先确认密钥来源、可用范围、有效期及是否支持重置/撤销。
- 禁止在代码、提示词、日志或输出文件中硬编码/明文暴露密钥。
---
使用指南
直接用自然语言描述查询需求,无需记忆命令。
常用说法速查
| 意图 | 示例话术 | 效果 |
|---|---|---|
| 查询账号作品 | 「爬取周幺姑家常菜的抖音作品」 | 获取账号基础信息 + 近期作品列表 + 数据亮点分析 |
| 精准查询 | 「帮我查询抖音号 cdjjc028 的作品」 | 按抖音号精准匹配,避免昵称模糊 |
| 提交账号收录 | 「我的号查不到,抖音号是 1212_1234」 | 提交收录请求,约 30 分钟后可再次查询 |
| 导出数据 | 「导出周幺姑家常菜的作品数据」 | 获取结构化作品数据 |
输出示例
完成查询后,你将收到以下结构化的结果:
账号基础信息:昵称(可点击跳转主页)、抖音号、地域、粉丝数、获赞、作品总数、红狐指数
近期作品列表(最多 50 条,按发布时间倒序):
| # | 发布时间 | 标题 | 点赞 | 评论 | 分享 | 互动 | 链接 | | … | … | … | … | … | … | … | 可点击跳转原视频 |
数据亮点:互动量 TOP3 作品分析 + 账号特征(更新频率、内容方向、互动表现、爆款特征)
---
(查询不到数据时,系统引导回复抖音号提交收录,30 分钟后自动同步。)
---
使用场景
| 场景 | 角色 | 示例问法 | 收益 |
|---|---|---|---|
| 品牌竞品监测 | 品牌营销经理 | 「帮我查一下竞品抖音号的作品数据和互动表现」 | 及时掌握竞品内容动态,优化自身策略 |
| MCN 达人评估 | MCN 运营人员 | 「帮我看看这个达人的粉丝数、获赞和近期作品数据」 | 快速评估达人价值,辅助签约决策 |
| 内容优化学习 | 抖音创作者 | 「帮我查同领域头部账号的作品,分析爆款特征」 | 找到内容优化方向,提升账号互动表现 |
| 数据分析报告 | 数据分析师 | 「帮我导出这几个抖音号的作品数据做分析」 | 高效获取结构化数据,支撑分析报告 |
---
重要数据说明
- 作品列表为近期作品数据,最多 50 条,按发布时间倒序排列,非账号全部历史作品。
- 数字格式:≥1 万显示为
x.xw(如 3.2w),≥1 亿显示为x.x亿,<1 万用千分位逗号。 - 抖音昵称不唯一,用昵称查询可能返回模糊匹配结果,建议用抖音号进行精准查询。
- 查询不到的账号支持提交收录,约 30 分钟后自动同步数据。
- 所有数据唯一来源为数据平台,不会从第三方渠道补充或估算。
---
核心技能逻辑
本文件为 douyin-works-crawler 技能的完整执行逻辑参考,SKILL.md 通过引用本文件获取详细规则。
---
1. 数据来源
唯一数据源:红狐数据API
1.1 查询接口
| 配置项 | 值 |
|---|---|
| 接口地址 | POST https://redfox.hk/story/api/dyData/queryUserWithWorks |
| 认证 | 请求头 X-API-KEY(环境变量 REDFOX_API_KEY,格式 ak_xxx) |
| 积分 | 是(resourceId: /story/api/dyData/queryUserWithWorks) |
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
accountId | String | 否* | 抖音号/uid(支持 unique_id、short_id、uid 任一匹配) |
accountName | String | 否* | 作者/账号名 |
source | String | 否 | 调用来源(默认:抖音作品抓取-GitHub) |
*accountId和accountName至少传一个
查询精准度提醒: 抖音昵称不唯一,使用accountName可能返回首个模糊匹配账号。若需精准查询,建议使用accountId(抖音号)。
响应字段:
- 账号级:nickname / accountId / uniqueId / uid / secUid / province / city / ipLocation / followerCount / awemeCount / totalFavorited / redfoxIndex
- 作品级(workList,近期作品数据,最多50条,按发布时间倒序):title / likeCount / commentCount / shareCount / interactiveCount / publishTime / url
数据范围说明:
- API返回的
workList为近期作品数据,最多50条,按发布时间倒序排列 - 实际返回数量取决于账号发布频率,通常为 1~50 条
awemeCount字段为账号历史作品总数,workList中的数量可能小于该值- 若账号近期无作品或作品未被收录,workList 为空列表
1.2 账号收录接口
| 配置项 | 值 |
|---|---|
| 接口地址 | POST https://redfox.hk/dyUser/syncUserNotes |
| 认证 | 请求头 X-API-KEY(环境变量 REDFOX_API_KEY,格式 ak_xxx) |
| 积分 | 是(resourceId: /dyUser/syncUserNotes) |
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
accountId | String | 是 | 抖音账号ID(支持 unique_id、short_id、uid 任一匹配) |
source | String | 否 | 调用来源(默认:抖音作品抓取-GitHub) |
响应说明: 异步同步触发接口,调用成功返回 HTTP 200,无响应体。系统异步拉取账号文章/作品数据,约30分钟后可查询。
错误码: 200=成功 | 400=参数错误 | 500=业务异常
---
2. 查询未命中处理
当查询未找到目标账号时,严禁联网搜索,按以下流程处理:
1. 匹配到错误账号 → 提示:"昵称查询返回的是「[实际匹配的昵称]」,非您要找的账号。请提供目标账号的抖音号进行精准查询。" 2. 未查询到账号 → 输出账号收录提示,引导用户进行账号收录:
未查询到当前账号的相关信息,可提交当前抖音账号进行账号收录。
1. 回复抖音号(在抖音个人主页显示的ID,如 1212_1234),即可进行账号收录。30分钟后将自动为您推作品查询报告~
2. 下次再说;3. 用户回复抖音号 → 调用账号收录接口 POST /dyUser/syncUserNotes,传入用户提供的抖音号作为 accountId,触发异步同步任务 4. 用户选择"下次再说" → 结束当前流程
收录成功后提示: "已提交账号收录请求,系统正在同步数据,约30分钟后可再次查询该账号的作品数据。"
收录失败提示: 根据错误码告知用户具体原因。
降级策略
API调用失败(如积分不足、网络异常)时明确告知用户错误原因,严禁联网搜索、严禁从第三方渠道估算或补充API未返回的字段。
---
3. 输出模板
使用说明: 严格按模板输出,不可省略章节。数据来源于API,如实展示。
数字格式规范: ≥1万用 w(如 3.2w),≥1亿用 亿(如 1.5亿),<1万用千分位逗号(如 8,642)。
链接列格式: 有url时显示 [链接](url),无url时显示 -。
昵称链接格式: 昵称字段使用 [nickname](https://www.douyin.com/user/{secUid}) 格式,secUid 为空时显示纯文本。
## 🎬 [nickname] - 抖音作品数据
### 账号基础信息
| 昵称 | 抖音号 | UID | 地域 | 粉丝数 | 获赞 | 作品总数 | 红狐指数 |
|------|--------|-----|------|--------|------|---------|---------|
| [nickname](https://www.douyin.com/user/[secUid]) | [accountId] | [uid] | [province·city] | [followerCount] | [totalFavorited] | [awemeCount] | [redfoxIndex] |
---
### 近期作品(共[N]条)
| # | 发布时间 | 标题 | 点赞 | 评论 | 分享 | 互动 | 链接 |
|---|---------|------|------|------|------|------|------|
| 1 | [publishTime] | [title] | [likeCount] | [commentCount] | [shareCount] | [interactiveCount] | [链接](url) / - |
> 作品列表为近期作品数据,最多50条(按发布时间倒序),账号历史作品总数为 [awemeCount] 条。
---
### 数据亮点
#### 互动量TOP3
🥇 **[title]**(互动[interactiveCount])
> [根据账号数据、作品内容、内容定位等总结该作品值得学习点]
🥈 **[title]**(互动[interactiveCount])
> [根据账号数据、作品内容、内容定位等总结该作品值得学习点]
🥉 **[title]**(互动[interactiveCount])
> [根据账号数据、作品内容、内容定位等总结该作品值得学习点]
#### 账号特征分析
- **更新频率:** [基于近期作品发布间隔分析]
- **内容方向:** [基于作品标题关键词归纳内容赛道]
- **互动表现:** [基于互动数据整体趋势分析]
- **爆款特征:** [基于TOP3作品共性总结]
---
### 数据说明
- **数据范围:** 近期作品数据,最多50条,按发布时间倒序
- **作品链接:** 接口返回url字段,提供作品直达链接;url为空时显示"-"
- **数字格式:** ≥1万显示为x.xw(如3.2w),≥1亿显示为x.x亿,<1万用千分位逗号
- **数据来源:** 红狐数据API
*爬取时间:[YYYY-MM-DD HH:mm]*---
4. 脚本调用
⚠️ 单次调用原则: 每次查询仅执行一次脚本调用,使用默认的 markdown 输出即可获得完整格式化报告,禁止重复调用(如先json再markdown)以避免浪费API积分。查询账号作品:
python3 scripts/douyin_works_fetcher.py --account "抖音名称或抖音号"提交账号收录:
python3 scripts/douyin_works_fetcher.py --account "任意" --sync "抖音号"参数说明:
| 参数 | 说明 |
|---|---|
--account | 抖音昵称或抖音号(自动识别:含中文→昵称,非中文→抖音号) |
--output | 输出格式:markdown(默认)/ json |
--sync | 提交账号收录,传入抖音号触发异步同步 |
自动识别逻辑:
- 输入含中文 → 使用
accountName参数查询(昵称模糊匹配) - 输入非中文 → 使用
accountId参数查询(抖音号精准匹配)
---
5. 注意事项
- 🔌 唯一数据源: 所有数据仅从红狐API获取,不使用第三方渠道补充或估算
- 📊 数据范围: 近期作品数据,最多50条,非账号全部历史作品
- 🔢 数字格式: ≥1万显示为
x.xw(如3.2w),≥1亿显示为x.x亿,<1万用千分位逗号(如8,642) - 🔗 作品链接: 接口返回url字段,表格中显示为
[链接](url),无url时显示- - ❌ 未查询到账号: API返回空数据时,输出账号收录提示文案,引导用户回复抖音号进行账号收录,严禁联网搜索、严禁生成无依据报告
- 📥 账号收录: 用户回复抖音号后,调用
POST /dyUser/syncUserNotes接口提交收录请求,约30分钟后可再次查询 - ❌ 昵称匹配到错误账号: 提示用户当前匹配结果非目标账号,引导提供抖音号重新查询,严禁联网搜索
- ✅ 如实输出: 作品数量如实展示
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
抖音作品爬取 - API调用脚本
基于红狐API接口 /story/api/dyData/queryUserWithWorks 查询抖音账号数据和近期作品列表
"""
import os
import json
import re
import argparse
import urllib.request
import urllib.error
from datetime import datetime
from typing import Dict, Optional
class DouyinWorksFetcher:
"""抖音作品爬取 - 红狐数据API"""
BASE_URL = "https://redfox.hk"
QUERY_ENDPOINT = "/story/api/dyData/queryUserWithWorks"
SYNC_ENDPOINT = "/dyUser/syncUserNotes"
ENV_VAR = "REDFOX_API_KEY"
def __init__(self, api_key: Optional[str] = None):
self.api_key = api_key or os.environ.get(self.ENV_VAR, "")
self.headers = {
"Content-Type": "application/json",
"X-API-KEY": self.api_key
}
def _is_chinese(self, text: str) -> bool:
"""判断输入是否包含中文字符"""
return bool(re.search(r'[\u4e00-\u9fff]', text))
def _make_request(self, endpoint: str, payload: Dict) -> Dict:
"""发送API请求"""
url = f"{self.BASE_URL}{endpoint}"
data = json.dumps(payload, ensure_ascii=False).encode("utf-8")
req = urllib.request.Request(url, data=data, method="POST")
for key, value in self.headers.items():
req.add_header(key, value)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
result = json.loads(resp.read().decode("utf-8"))
return result
except urllib.error.HTTPError as e:
body = ""
try:
body = e.read().decode("utf-8")
except Exception:
pass
# 红狐API限流时可能返回HTML错误页
if "<html" in body.lower():
return {"code": -2, "data": None, "msg": "API限流或服务异常,请稍后重试"}
return {"code": e.code, "data": None, "msg": f"HTTP {e.code}: {body[:200]}"}
except urllib.error.URLError as e:
return {"code": -1, "data": None, "msg": f"连接失败: {e.reason}"}
except Exception as e:
return {"code": -1, "data": None, "msg": f"请求异常: {e}"}
def query_account(self, account: str) -> Dict:
"""
查询抖音账号信息+作品
Args:
account: 抖音昵称或抖音号(自动识别)
Returns:
dict: {
"success": bool,
"account": dict or None,
"works": list,
"error": str or None
}
"""
# 自动识别输入类型,构建请求参数(单值,非列表)
if self._is_chinese(account):
payload = {"accountName": account, "source": "抖音作品抓取-GitHub"}
query_mode = "accountName"
else:
payload = {"accountId": account, "source": "抖音作品抓取-GitHub"}
query_mode = "accountId"
print(f"🔍 正在查询抖音账号: {account} (模式: {query_mode})")
result = self._make_request(self.QUERY_ENDPOINT, payload)
code = result.get("code")
msg = result.get("msg", "")
data = result.get("data")
# 成功码为2000(红狐平台统一成功码)
# data为空或关键字段(nickname)为空时视为未查询到账号
has_valid_data = data and data.get("nickname")
if code == 2000 and has_valid_data:
account_info = self._extract_account_info(data)
works = data.get("workList", [])
# 昵称查询时,提醒用户确认是否为目标账号
if query_mode == "accountName" and account_info.get('nickname', '') != account:
print(f"⚠️ 昵称查询返回的是「{account_info['nickname']}」,非您输入的「{account}」")
print(f" 若非目标账号,请提供抖音号精准查询")
print(f"✅ 查询成功: {account_info['nickname']} (粉丝: {format_number(account_info['followerCount'])})")
print(f" 作品总数: {account_info['awemeCount']} | 爬取作品: {len(works)}条")
return {
"success": True,
"account": account_info,
"works": works,
"error": None
}
# 未找到账号(code=2000但data为空/无效,或code=500)
if code == 2000 and not has_valid_data:
return {
"success": False,
"account": None,
"works": [],
"error": None,
"need_sync": True
}
if code == 500 and "未找到" in msg:
return {
"success": False,
"account": None,
"works": [],
"error": None,
"need_sync": True
}
# 参数错误
if code == 400:
return {
"success": False,
"account": None,
"works": [],
"error": f"请求参数错误: {msg}"
}
# 其他错误(限流、网络异常等)
return {
"success": False,
"account": None,
"works": [],
"error": f"API错误(code={code}): {msg}"
}
def sync_account(self, account_id: str, source: str = "抖音作品抓取-GitHub") -> Dict:
"""
提交账号收录请求(异步同步触发)
Args:
account_id: 抖音账号ID(抖音号/uid)
source: 调用来源
Returns:
dict: {"success": bool, "error": str or None}
"""
payload = {"accountId": account_id, "source": source}
print(f"📥 正在提交账号收录: {account_id}")
result = self._make_request(self.SYNC_ENDPOINT, payload)
code = result.get("code")
msg = result.get("msg", "")
# 成功码200(该接口成功码为200,无响应体)
if code == 200:
print(f"✅ 账号收录请求已提交,约30分钟后可查询")
return {
"success": True,
"error": None
}
# 参数错误
if code == 400:
error_msg = f"账号收录失败(参数错误): {msg}"
print(f"❌ {error_msg}")
return {
"success": False,
"error": error_msg
}
# 其他错误
error_msg = f"账号收录失败(code={code}): {msg}"
print(f"❌ {error_msg}")
return {
"success": False,
"error": error_msg
}
def _extract_account_info(self, data: Dict) -> Dict:
"""提取账号基础信息"""
return {
"nickname": data.get("nickname", ""),
"accountId": data.get("accountId", ""),
"uniqueId": data.get("uniqueId", ""),
"uid": data.get("uid", ""),
"secUid": data.get("secUid", ""),
"province": data.get("province", ""),
"city": data.get("city", ""),
"ipLocation": data.get("ipLocation", ""),
"followerCount": data.get("followerCount", 0),
"awemeCount": data.get("awemeCount", 0),
"totalFavorited": data.get("totalFavorited", 0),
"redfoxIndex": data.get("redfoxIndex"),
}
def format_markdown(self, result: Dict) -> str:
"""格式化为Markdown输出"""
if not result["success"]:
# 账号未查询到,输出收录提示
if result.get("need_sync"):
lines = []
lines.append("未查询到当前账号的相关信息,可提交当前抖音账号进行账号收录。")
lines.append("")
lines.append("1. 回复抖音号(在抖音个人主页显示的ID,如 1212_1234),即可进行账号收录。30分钟后将自动为您推作品查询报告~")
lines.append("2. 下次再说;")
return "\n".join(lines)
return f"❌ 查询失败: {result['error']}"
account = result["account"]
works = result["works"]
now = datetime.now().strftime("%Y-%m-%d %H:%M")
location = f"{account['province']}·{account['city']}" if account['province'] else account.get('ipLocation', '-')
redfox_index = account.get('redfoxIndex')
redfox_str = str(redfox_index) if redfox_index is not None else '-'
# 昵称拼接secUid跳转链接
nickname_display = f"[{account['nickname']}](https://www.douyin.com/user/{account['secUid']})" if account.get('secUid') else account['nickname']
lines = []
lines.append(f"## 🎬 {account['nickname']} - 抖音作品数据")
lines.append("")
lines.append("### 账号基础信息")
lines.append("")
lines.append("| 昵称 | 抖音号 | UID | 地域 | 粉丝数 | 获赞 | 作品总数 | 红狐指数 |")
lines.append("|------|--------|-----|------|--------|------|---------|---------|")
lines.append(
f"| {nickname_display} | {account['accountId']} | {account['uid']} "
f"| {location} | {format_number(account['followerCount'])} "
f"| {format_number(account['totalFavorited'])} | {account['awemeCount']} "
f"| {redfox_str} |"
)
lines.append("")
lines.append("---")
lines.append("")
# 作品列表
lines.append(f"### 近期作品(共{len(works)}条)")
lines.append("")
if works:
lines.append("| # | 发布时间 | 标题 | 点赞 | 评论 | 分享 | 互动 | 链接 |")
lines.append("|---|---------|------|------|------|------|------|------|")
for i, work in enumerate(works, 1):
title = (work.get("title") or "无标题")[:40]
publish_time = work.get("publishTime", "-")
like = format_number(work.get("likeCount"))
comment = format_number(work.get("commentCount"))
share = format_number(work.get("shareCount"))
interactive = format_number(work.get("interactiveCount"))
url = work.get("url", "")
url_display = f"[链接]({url})" if url else "-"
lines.append(
f"| {i} | {publish_time} | {title} | {like} | {comment} | {share} | {interactive} | {url_display} |"
)
else:
lines.append("> 暂无作品数据")
lines.append("")
lines.append(f"> 作品列表为近期作品数据,最多50条(按发布时间倒序),账号历史作品总数为 {account['awemeCount']} 条。")
lines.append("")
lines.append("---")
lines.append("")
# 数据亮点 - 互动量TOP3 + 账号特征分析
if works:
lines.append("### 数据亮点")
lines.append("")
# 互动量TOP3(列表格式,展示作品分析)
sorted_works = sorted(works, key=lambda w: int(w.get("interactiveCount", 0) or 0), reverse=True)
top3 = sorted_works[:3]
medals = ["🥇", "🥈", "🥉"]
lines.append("#### 互动量TOP3")
lines.append("")
for idx, work in enumerate(top3):
title = (work.get("title") or "无标题")[:50]
interactive = int(work.get("interactiveCount", 0) or 0)
like = int(work.get("likeCount", 0) or 0)
comment = int(work.get("commentCount", 0) or 0)
share = int(work.get("shareCount", 0) or 0)
# 生成作品分析:基于账号数据、作品内容、内容定位等总结值得学习点
analysis_parts = []
# 互动结构分析
if interactive > 0:
like_ratio = like / interactive
comment_ratio = comment / interactive
share_ratio = share / interactive
if share_ratio > 0.3:
analysis_parts.append(f"分享率达{share_ratio*100:.0f}%,传播力极强,用户主动转发意愿高")
elif share_ratio > 0.15:
analysis_parts.append(f"分享率{share_ratio*100:.0f}%,具备较强传播属性")
if comment_ratio > 0.1:
analysis_parts.append(f"评论率{comment_ratio*100:.0f}%,用户参与讨论热烈")
if like_ratio > 0.85:
analysis_parts.append("互动以点赞为主,粉丝粘性高但传播深度有限")
# 内容特征分析
title_text = work.get("title") or ""
if "#" in title_text:
analysis_parts.append("标题善用话题标签,借势公域流量扩大曝光")
if "@" in title_text:
analysis_parts.append("内容@关联账号,形成互动联动效应")
if any(kw in title_text for kw in ["恭喜", "获得", "荣获"]):
analysis_parts.append("获奖/荣誉类内容自带话题热度,易引发粉丝共鸣")
if any(kw in title_text for kw in ["教程", "做法", "怎么做"]):
analysis_parts.append("教程类内容实用性强,用户收藏转发意愿高")
if any(kw in title_text for kw in ["幕后", "花絮", "日常"]):
analysis_parts.append("幕后/花絮类内容拉近与粉丝距离,增强亲和力")
# 粉丝互动比分析
follower_count = account.get('followerCount', 0) or 0
if follower_count > 0 and interactive > 0:
interaction_fan_ratio = interactive / follower_count
if interaction_fan_ratio > 0.1:
analysis_parts.append(f"互动/粉丝比达{interaction_fan_ratio*100:.1f}%,粉丝转化效率极高")
elif interaction_fan_ratio > 0.05:
analysis_parts.append(f"互动/粉丝比{interaction_fan_ratio*100:.1f}%,粉丝活跃度良好")
analysis = ";".join(analysis_parts) if analysis_parts else "该作品互动表现突出,值得关注"
lines.append(f"{medals[idx]} **{title}**(互动{format_number(interactive)})")
lines.append(f"> {analysis}")
lines.append("")
# 账号特征分析
lines.append("#### 账号特征分析")
lines.append("")
# 更新频率分析
publish_times = []
for w in works:
pt = w.get("publishTime", "")
if pt:
try:
dt = datetime.strptime(pt, "%Y-%m-%d %H:%M:%S")
publish_times.append(dt)
except ValueError:
pass
if len(publish_times) >= 2:
publish_times.sort(reverse=True)
gaps = [(publish_times[i] - publish_times[i + 1]).days for i in range(len(publish_times) - 1)]
avg_gap = sum(gaps) / len(gaps)
if avg_gap < 1.5:
freq_desc = f"高频更新,平均每{avg_gap:.1f}天发布1条"
elif avg_gap < 4:
freq_desc = f"稳定更新,平均每{avg_gap:.1f}天发布1条"
else:
freq_desc = f"低频更新,平均每{avg_gap:.1f}天发布1条"
else:
freq_desc = f"近期发布{len(works)}条作品"
lines.append(f"- **更新频率:** {freq_desc}")
# 互动表现分析
total_interactive = sum(int(w.get("interactiveCount", 0) or 0) for w in works)
avg_interactive = total_interactive / len(works) if works else 0
max_interactive = max(int(w.get("interactiveCount", 0) or 0) for w in works) if works else 0
min_interactive = min(int(w.get("interactiveCount", 0) or 0) for w in works) if works else 0
lines.append(f"- **互动表现:** 平均互动{format_number(avg_interactive)},最高{format_number(max_interactive)},最低{format_number(min_interactive)}")
# 爆款特征
if top3:
top3_avg = sum(int(w.get("interactiveCount", 0) or 0) for w in top3) / len(top3)
overall_avg = avg_interactive
if overall_avg > 0:
ratio = top3_avg / overall_avg
hot_desc = f"TOP3平均互动{format_number(top3_avg)},是整体均值的{ratio:.1f}倍"
else:
hot_desc = f"TOP3平均互动{format_number(top3_avg)}"
lines.append(f"- **爆款特征:** {hot_desc}")
lines.append("")
lines.append("---")
lines.append("")
lines.append("### 数据说明")
lines.append("")
lines.append("- **数据范围:** 近期作品数据,最多50条,按发布时间倒序")
lines.append("- **作品链接:** 接口返回url字段,提供作品直达链接")
lines.append("- **数据来源:** 红狐数据API")
lines.append("")
lines.append(f"*爬取时间:{now}*")
return "\n".join(lines)
def format_json(self, result: Dict) -> str:
"""格式化为JSON输出"""
return json.dumps(result, ensure_ascii=False, indent=2)
def format_number(num) -> str:
"""格式化数字显示"""
if num is None:
return "-"
try:
num = int(num)
except (ValueError, TypeError):
return str(num)
if num >= 100000000:
return f"{num / 100000000:.1f}亿"
elif num >= 10000:
return f"{num / 10000:.1f}w"
else:
return f"{num:,}"
def main():
parser = argparse.ArgumentParser(description="抖音作品爬取工具")
parser.add_argument("--account", required=True, help="抖音昵称或抖音号")
parser.add_argument("--output", choices=["markdown", "json"], default="markdown", help="输出格式(默认markdown)")
parser.add_argument("--sync", help="提交账号收录,传入抖音号")
args = parser.parse_args()
fetcher = DouyinWorksFetcher()
if not fetcher.api_key:
print(f"❌ 未设置环境变量 {DouyinWorksFetcher.ENV_VAR}")
print(f"💡 请先运行: export {DouyinWorksFetcher.ENV_VAR}=你的API密钥值")
return
print(f"✅ API Key已配置: {fetcher.api_key[:8]}...")
# 账号收录模式
if args.sync:
sync_result = fetcher.sync_account(args.sync)
if args.output == "json":
print(json.dumps(sync_result, ensure_ascii=False, indent=2))
else:
if sync_result["success"]:
print("\n✅ 已提交账号收录请求,系统正在同步数据,约30分钟后可再次查询该账号的作品数据。")
else:
print(f"\n❌ {sync_result['error']}")
return
# 查询模式
result = fetcher.query_account(args.account)
if args.output == "json":
print(fetcher.format_json(result))
else:
print(fetcher.format_markdown(result))
if not result["success"] and not result.get("need_sync"):
print(f"\n💡 提示:请提供目标账号的抖音号进行精准查询,避免昵称模糊匹配错误。")
if __name__ == "__main__":
main()