Files
Evil0ctal f40160ede5 docs: add a NOTICE file carrying the copyright notice
The README asked redistributors to keep "the copyright notice", and the
repository had none: the only candidate was the placeholder line in the
LICENSE appendix, which is Apache's how-to template and stays verbatim.
NOTICE is where Apache 2.0 section 4(d) expects attribution to live.

Closes #766
2026-09-28 11:40:12 -07:00

28 KiB
Raw Permalink Blame History

Douyin_TikTok_Download_API

Douyin_TikTok_Download_API

English | 简体中文

🚀 自部署的抖音 / TikTok数据接口服务。一条 docker compose up,自动维护身份池,对外提供 REST API、MCP 与 Web 控制台。

开源、免费、跑在你自己的机器上 —— 不用注册、没有配额、链路上没有第三方。它能取作品、作者、评论和搜索,下载视频和图集时拿到的是无水印的流(它挑的是平台本来就提供的那条干净流,而不是「去掉」了什么),采集到的内容存在你自己的 PostgreSQL 里。

GitHub license Release Version GitHub Star GitHub forks GitHub issues
CI CodeQL Last commit
Website Live demo Python MCP Docker Pulls Docker Image Size

💖 赞助商

这些赞助商已付费放置在这里,Douyin_TikTok_Download_API 项目将永远免费且开源。如果您希望成为该项目的赞助商,请查看我的 GitHub 赞助商页面。

TikHub.io - 全球社交媒体数据与 API 市场

TikHub.io

你的一站式社交媒体数据与 API 市场

为抖音、小红书、TikTok、Instagram、YouTube、Twitter 等平台提供专业数据方案。
实时数据 · 灵活接口 · 无缝集成 · 有竞争力的价格与折扣

在 TikHub.io 市场买卖定制 API、服务与社交媒体解决方案,
加入一个由开发者、企业与内容创作者组成的活跃生态。

多家全球领先的红人营销与社交媒体情报平台正在使用

→ 前往 TikHub.io  ·  API 文档

🧩 REER —— 逆向工程交流论坛

一个放东西的地方。这个项目之所以存在,是因为有人把「某个签名是怎么构造出来的」写了下来; 论坛是为了下一轮这种事 —— 签名、协议、加壳,凡是被拆开过的都算。

免费、无广告,除了显而易见的那几条之外基本没有条款限制。中英双语,注册即可发布,不设门槛。

🎬 长这样

DTK 控制台:总览、身份池、调度器、调试台、资料库、下载、接口文档与 MCP

一次真实的调用:粘链接、发请求、拿到归一化后的结果,途中经过的身份池、调度器和接口文档都在同一个控制台里。 界面跟着浏览器语言走,中英文都是手写的,不是机翻。English UI

不用装任何东西就能试

https://demo.douyin.wtf 是一个对所有人开放的在线实例。登录进去即可 —— 登录页会替你 填好演示账号 —— 然后随便用:调试台、调度器、资料库、接口文档。同一个账号还带一把 API Key,可以直接调爬虫接口,在 API Key 页面上是明文显示的。

它是只读的。演示请求不写入请求日志和归档库,所以一个公开实例的数据库不会被陌生人撑爆; 关掉演示模式,所有演示会话立即失效,那把 Key 也立刻作废。

限流:每 10 秒 30 次请求。 超了会进入 10 秒冷却,期间你的任何请求都会被拒绝。 这是一台共用的实例,它背后的身份池是所有人同时使用时的上限。

演示站的用途是帮你判断要不要自己部署一套。它不是一个可以拿来对接的服务 —— 它可能挂、 可能被重置、也可能被关掉,而且不会提前通知。

🚀 v4 与 v5

v5 是一次重写,从空分支起步,没有继承 v4 的任何代码。

v4 最大的问题从来不是功能少,而是接口会悄悄死掉,而你不知道。Cookie 过期、签名算法变更、 某个接口被风控,通常都要等到有人来提 issue 才发现。v5 把"看得见"和"能自愈"排在功能前面。

v4 v5
身份从哪来 从浏览器里抠 Cookie,粘进 config.yaml 无头浏览器自动铸造游客身份,可用数不够时自己补
请求怎么发 有请求就发出去 健康度分层、量化 LRU 轮换、每身份独占锁、每(身份,接口)令牌桶、接口级熔断
出了问题 等别人报错 每次请求一条结构化记录,身份和接口都有实时健康度,控制台上看得见
调用方式 同步,发出去等着 默认异步(202 + task_id),加 ?wait= 就退回同步
数据留存 解析完即弃 PostgreSQL + Redis;解析过的内容自动归档,平台删了这里还在
访问控制 没有,谁都能调 API Key + 作用域 + 角色,控制台里管
界面 PyWebIO 单页 React 控制台:身份池、调度器、资料库、下载、日志、诊断
接入方式 REST REST + MCP + CLI,共用同一个 service 层
签名 X-Bogus、A_Bogus a_bogus、X-Bogus、X-Gnarly、X-Dynosaur,纯 Python 实现,另有浏览器兜底
部署 pip install -r requirements.txt + python start.py docker compose up,三个镜像
平台 抖音、TikTok、哔哩哔哩 抖音、TikTok

哔哩哔哩是唯一退步的一项:v5 暂时没有。它和抖音 / TikTok 不共用签名和身份体系, 重写时先放下了,之后再说。

还在用 v4?

v4 的代码保留在 v4 分支, 镜像也还在推,一条命令就能起:

docker run -d --name dtk-v4 --restart unless-stopped \
  -p 8080:80 evil0ctal/douyin_tiktok_download_api:V4.1.2

然后打开 http://localhost:8080,接口文档在 /docs。端口特意错开成 8080,v5 占的是 8000,两个版本可以在同一台机器上一起跑。

用之前先把抖音 cookie 换掉。 v4 没有身份池,镜像里那份 cookie 是打包时带的,早就 过期了,不换的话抖音那边一律返回 400:

docker cp dtk-v4:/app/crawlers/douyin/web/config.yaml ./douyin-web.yaml
# 把文件里的 Cookie 换成浏览器里的,保存
docker rm -f dtk-v4
docker run -d --name dtk-v4 --restart unless-stopped -p 8080:80 \
  -v "$PWD/douyin-web.yaml:/app/crawlers/douyin/web/config.yaml" \
  evil0ctal/douyin_tiktok_download_api:V4.1.2

TikTok 的两份配置在 /app/crawlers/tiktok/web/config.yaml 和 /app/crawlers/tiktok/app/config.yaml,要改的话一样挂进去。

想用 compose 管着,写一个文件就够 —— 前提是 douyin-web.yaml 已经按上面拷到同级目录, 不然 docker 会按这个名字建一个目录,程序读配置直接起不来:

# compose.yml
services:
  app:
    image: evil0ctal/douyin_tiktok_download_api:V4.1.2
    container_name: dtk-v4
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      TZ: Asia/Shanghai
    volumes:
      - ./douyin-web.yaml:/app/crawlers/douyin/web/config.yaml
docker rm -f dtk-v4   # 上面 docker run 起的那个占着同一个名字
docker compose -p dtk-v4 up -d

main 现在是 v5,latest 跟着 main 走,想留在 v4 就固定 tag,别用 latest。 V4.1.2 是 v4 最后一个发布版;之后 v4 分支又合了几个 PR(B 站下载、cookie 热更新), 那份代码对应的镜像 tag 是 commit sha 5be4838。

v4 没有一键脚本,下面「快速开始」里那个装的是 v5。v4 就上面这些:分支还收 PR,但不会 再往上加东西了,新装的话直接上 v5。

一起写点什么

有几个开源项目的交流群,想一起做这个项目、或者只是想聊聊技术的, 都可以加微信 Evil0ctal,备注 github 交流,我拉你进群。

群里可以互相交流学习,不允许发广告以及违法的东西,纯粹交朋友和技术交流。

📦 它能从抖音和 TikTok 取什么

能力 抖音 TikTok
单条作品详情(视频 / 图集) ✅ ✅
作者资料 ✅ ✅
作者作品列表 ✅ ✅
作者喜欢列表 ✅ ✅
合集 / 播放列表 ✅ ✅
评论 ✅ ✅
评论回复 ✅ ✅
粉丝列表 ❌ ✅
关注列表 ❌ ✅

抖音的粉丝和关注列表只对已登录会话开放,游客身份拿不到,所以这两个接口干脆没注册: 注册一个永远返回空页的接口没意义。导入你自己的登录 Cookie 之后,其余接口能看到的内容也会更多。

媒体下载、内容归档、计数快照、合集、定时监控都是内置的,不需要额外服务。

🔗 它认得哪些抖音 / TikTok 链接

粘贴什么都行——分享短链、作品页地址,或者 App 复制出来的一整段带文案的口令:

https://v.douyin.com/L4NpDJ6/
https://www.douyin.com/video/7126745726494821640
https://www.douyin.com/jingxuan?modal_id=7660875690212492466
https://www.tiktok.com/@evil0ctal/video/7156033831819037994
https://www.tiktok.com/t/ZTR9nkkmL/
2.84 nqe:/ 骑白马的也可以是公主%%百万转场变身 https://v.douyin.com/L4FJNR3/ 复制此链接,打开Dou音搜索

短链会自动跟随展开,文案里的链接会被提取出来。作品 ID 还会先按平台自己的编码规则校验一遍, 一个不可能存在的 ID 在这里就被拒掉,不会浪费一次上游请求。

⚗️ 技术栈

服务端 Python 3.12 · FastAPI · SQLAlchemy 2.0(async)· Alembic · Typer · structlog
传输 wreq(浏览器 TLS 指纹模拟)· httpx
数据 PostgreSQL + TimescaleDB · Redis
控制台 React 19 · TypeScript · Vite · TanStack Query · wouter · i18next
签名 a_bogus / X-Bogus / X-Gnarly / X-Dynosaur,纯 Python 实现
身份铸造 CloakBrowser 无头浏览器,单独一个容器,通过 HTTP 调用
下载器 Go 1.23,只用标准库,静态编译进 scratch 镜像
鉴权 argon2id 口令哈希 · API Key + 作用域
对外协议 REST(OpenAPI)· MCP(streamable-http)· CLI
工程 uv · ruff · mypy · pytest · Docker Compose

除了 Postgres 和 Redis,不需要任何其它基础设施——没有 Kafka、没有 Elasticsearch、 没有对象存储、没有 k8s。

CloakBrowser 的版本 pin 在一个指定的 commit 上。这是一项安全控制,见 docker/Dockerfile.browser。

🗂 项目结构

先说一句 dtk 是什么。 仓库全称 Douyin_TikTok_Download_API 念起来太长,所以代码里一律用 DTK:Douyin + TiKTok,只取那两个平台,下载器和 API 那两截没进来。

它是 Python 包名(src/dtk/)、命令行(dtk --help)、每个环境变量的前缀(DTK_SECRET_KEY 这些)、 compose 的项目名(-p dtk),也是控制台标题栏里那三个字母。看到 dtk,说的就是 Douyin_TikTok_Download_API。

Douyin_TikTok_Download_API/
├── src/dtk/                服务端,代码全在这
│   ├── api/                FastAPI 路由、鉴权、OpenAPI 本地化
│   ├── platforms/          抖音 / TikTok 适配器:接口定义、参数、解析
│   ├── signing/            a_bogus / X-Bogus / X-Gnarly / X-Dynosaur
│   ├── transport/          出站请求、响应分类(正常 / 业务错误 / 风控 / 网络)
│   ├── identity/           身份铸造与健康度
│   ├── scheduler/          身份选取、令牌桶、熔断器
│   ├── services/           业务层,REST、MCP、CLI 共用
│   ├── worker/             异步任务、回调、定时收集
│   ├── db/                 SQLAlchemy 模型与 Alembic 迁移
│   ├── ops/                诊断、备份、健康检查、告警通知
│   ├── media/              下载器客户端
│   ├── models/             跨平台统一的内容模型
│   ├── urls/               链接识别、短链展开、ID 校验
│   ├── mcp/                MCP server
│   ├── cli/                dtk 命令行
│   ├── i18n/               服务端中英文案
│   └── core/               配置、日志、错误类型
├── web/                    React 控制台,构建产物打进应用镜像
│   └── src/
│       ├── pages/          每个控制台页面一个文件
│       ├── components/     设计系统与共用组件
│       └── locales/        控制台中英文案
├── docker/                 三个 Dockerfile、compose 与两个 sidecar
│   ├── browser_rpc/        Python,包装 CloakBrowser
│   ├── downloader/         Go,媒体下载 sidecar
│   └── compose.yml
├── documents/              用户文档,中英各 17 篇
├── tests/                  unit / integration / contract / replay
├── scripts/                smoke.sh
├── .github/workflows/      CI 与 Docker 镜像发布
├── alembic.ini
├── pyproject.toml
└── Makefile

⚡️ 快速开始:用 Docker 自部署

怕麻烦就用一键脚本,它会问你几个问题然后把整套跑起来 —— 会自己识别发行版、 检测有没有 Docker、按机器大小调好资源上限:

curl -fsSL https://raw.githubusercontent.com/Evil0ctal/Douyin_TikTok_Download_API/main/install/install.zh.sh -o install.zh.sh
less install.zh.sh    # 先读一遍再跑,这是个好习惯
bash install.zh.sh

装完之后,这个脚本就是运维工具。 再跑一次它会发现已有安装,打开菜单:看状态、升级(和 GitHub 最新 Release 比版本)、改口令、加管理员、备份恢复、改运行时设置、清磁盘、停止或卸载。--manage 直达菜单。

细节见 install/README.md。下面是手动的做法。

装法有两种,下面走的是推荐的那种。手动装依赖的路子见 不用 Docker。

装法 适合谁 详细步骤
Docker Compose(推荐) 绝大多数人,生产也包括在内 安装与部署 · 首次安装
手动装依赖 不能用 Docker,或者你要改代码 开发方式 · 裸机生产部署

在中国大陆的机器上装? 先换源再动手,不然多半卡在拉镜像那一步: 中国大陆的网络准备。

需要 Docker 和 Docker Compose。先把仓库拉下来——compose 文件、Dockerfile 和迁移脚本都在里面, 默认分支就是 v5:

git clone https://github.com/Evil0ctal/Douyin_TikTok_Download_API.git
cd Douyin_TikTok_Download_API

仓库里不带任何默认密码或密钥,接着生成 .env:

POSTGRES_PASSWORD=$(openssl rand -hex 24)
REDIS_PASSWORD=$(openssl rand -hex 24)
cat > .env <<EOF
DTK_SECRET_KEY=$(openssl rand -base64 48)
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
REDIS_PASSWORD=${REDIS_PASSWORD}
DTK_DATABASE_URL=postgresql+asyncpg://dtk:${POSTGRES_PASSWORD}@postgres:5432/dtk
DTK_REDIS_URL=redis://:${REDIS_PASSWORD}@redis:6379/0
EOF
docker compose -p dtk -f docker/compose.yml up -d
docker compose -p dtk -f docker/compose.yml logs api   # 打印首次初始化令牌

打开 http://127.0.0.1:8000,用日志里的令牌创建第一个管理员账号。

镜像从哪来

默认是本地构建:up 第一次会用仓库里的 Dockerfile 把应用镜像编出来,几分钟。 如果你不想在自己机器上编译,把 compose 指向已发布的镜像即可:

export DTK_IMAGE=evil0ctal/douyin_tiktok_download_api
export DTK_IMAGE_TAG=latest
docker compose -p dtk -f docker/compose.yml pull
docker compose -p dtk -f docker/compose.yml up -d

pull 这一步不能省:compose 里这些服务同时写了 image 和 build,本机没有这个镜像时 它会自己去编,而不是去拉。

镜像同时提供 linux/amd64 与 linux/arm64,所以 Apple Silicon 和树莓派上都是原生运行。 浏览器容器不发布——它会从一个指定的 commit 安装 CloakBrowser,那个 pin 是安全控制, 应当由你自己决定,所以它一直是本地构建。

不用 Docker

也支持,而且这就是这个项目本身的开发方式。你要自己准备 PostgreSQL 17(必须带 TimescaleDB 扩展, 普通 postgres:17 不行)、Redis 8、Python 3.12 和 uv;要构建控制台还需要 Node 22。两份步骤:

容器本来替你做的那些事——非 root 用户、内存和 CPU 上限、只读根文件系统、进程守护——裸机上都得自己补回来, 那一节把它们逐条列了出来。

还想知道什么

想做的事 去哪看
改容器规格、算机器要多大 三档配置 · 怎么改这些上限
开浏览器容器、下载器 sidecar 两个可选 profile
挂 TLS、放到反向代理后面 放在反向代理后面
环境变量到底怎么读的 环境变量
装完确认它真的好了 验证安装
compose 文件本身逐行解释 docker/README.md

🖥 用它做什么:控制台、REST API、MCP 和 CLI

入口 地址 说明
Web 控制台 / 身份池、调度器、资料库、下载、日志、诊断
接口文档 /docs 控制台内的 Swagger UI,中英双语
裸接口文档 /swagger、/redoc 无需登录
REST API /api/v1/... 93 个操作
MCP /mcp 与 REST 共用同一个 service 层,配置方法见控制台 /mcp-guide
CLI dtk --help 同上

主要能力:

  • 解析:链接、分享文案、短链、作品 ID 都吃
  • 归档:解析过的内容自动入库,平台删了这里还在
  • 下载:媒体存到自己磁盘,支持按作者批量、跳过已下载、去重
  • 关注列表:定期重新收集某个作者或作品
  • iOS 快捷指令:/api/v1/ios/shortcut

🔄 更新到新版本

控制台会替你留意:system.check_updates 默认开着,登录后如果有新版本会弹一次, 每 24 小时最多一次。那个请求是你的浏览器发给 GitHub 的,服务器不会往外发任何东西 ——所以它不会告诉任何人你这台实例存在。气人的话在设置里关掉。

更新本身就是拉镜像加重启。用脚本装的话,再跑一次选「升级」就行:

bash install.zh.sh --manage    # 选 2

手工版是这样:

cd /opt/dtk && git pull

# 用已发布镜像的(推荐):把 .env 里的 DTK_IMAGE_TAG 改成新版本
docker compose -p dtk -f docker/compose.yml pull api worker downloader
docker compose -p dtk -f docker/compose.yml run --rm migrate
docker compose -p dtk -f docker/compose.yml up -d

自己构建的话把 pull 换成 build。migrate 每次启动都会跑,Alembic 是幂等的, 所以单独跑那一步只是想在切换容器之前先把库升上去。

你的数据不会动。 命名卷(postgres-data、redis-data、media-data)不随容器 重建而消失,身份池、归档、设置和 API Key 都在原地。

浏览器镜像只有在 docker/Dockerfile.browser 或 CloakBrowser 的 pin 变了才需要重建, 一般的版本更新不用管它。

想回退就把 DTK_IMAGE_TAG 改回上一个 sha- 或版本号再 up -d。 迁移不提供自动降级——升级前备份数据库,这是唯一稳妥的回退路径。

📖 文档

在线阅读:douyin.wtf —— 同样的 17 篇,渲染好、可搜索、中英双语。 markdown 源文件在 documents/,站点就是拿它构建的, 所以两边永远不会对不上。

新手从这里开始: 快速开始 · 核心概念 · 控制台总览

部署与运维: 安装与部署 · 配置参考 · 运维 · 故障排查 · 安全

开发对接: REST API 指南 · MCP 与 AI 客户端 · 命令行参考 · 参与开发

接口参考手册不在文档里,而是由代码直接生成的:你自己的实例在 /docs(控制台内) 以及 /swagger、/redoc、/openapi.json(无需登录)提供,中英双语。

English documentation: documents/README.md

用 LLM 读这个项目? llms.txt 把整套文档整理成了一份带注解的索引, 格式是 llmstxt.org 约定的那种。

📮 联系方式

问题反馈 GitHub Issues —— 公开、有记录,遇到过同样问题的人也能回答你
邮箱 Evil0ctal1985@gmail.com —— 直达作者本人,适合不方便公开的内容
作者 @Evil0ctal

提问之前请先看故障排查,并附上自检页面或 dtk diagnose 的输出。它能回答维护者原本要反过来问你的大部分问题。

⭐️ Star 历史

Star History Chart

起始于 2021/11/06 · GitHub @Evil0ctal

📄 许可协议

Apache License 2.0。

你可以使用、修改、分发本项目,包括商业用途,也包括放进闭源产品。这项授权不可撤销。 作为交换,协议要求你:

  • 分发副本时保留协议全文和 NOTICE 文件(版权声明就在里面)
  • 在你改动过的文件里说明改了什么
  • 接受它不提供任何担保

作者的一个请求

这个项目是免费送出去的,它能一直免费是因为有赞助商,而不是因为向用户收费。 如果你靠它赚到了钱,请考虑也赞助一下,而不是只拿。

这是一个请求,不是协议条款——Apache 2.0 允许商业用途,上面这段话不会把这项权利收回去。

☕️ 赞赏作者

上面的赞助商付的是项目的钱;这一节是给维护它的人的,完全自愿。

网络 地址
Solana HvtkxmDERbNXfCoojpdFAYN5mSWowjpXgedsG9eF7y9z
Tron (TRC20) TQwSM2vjcnrdRU7gY7KNp2tCgMnK33azkT
Ethereum (ERC20) 0x2f210FdfD981B59eC130370E5b1Aa8A6a06fb5Ad
BNB Smart Chain (BEP20) 0x2f210FdfD981B59eC130370E5b1Aa8A6a06fb5Ad
Bitcoin bc1q785j55cxlnjqe8lkwy8cq57t8t9vn3ak9tlsfy

这些网络都支持常见的主流代币。TRC20 或 Solana 上的 USDT 最方便接收,手续费也最低。

只能按地址所属的网络转账。 转错链的资产任何人都无法找回。 以太坊和 BNB Smart Chain 共用同一个地址是正常的:两者都是 EVM 链,由同一把私钥控制。

也可以走 GitHub Sponsors。

你需要自己负责的部分

本项目从有自己服务条款的平台抓取数据,并且运行在你自己控制的机器上。 请遵守平台条款和所在地法律,尊重你所收集内容背后的人, 不要拿它去骚扰任何人,也不要拿它去二次分发不属于你的作品。这些没有别人能替你把关。