Skip to content

Repository files navigation

content-downloader

给一个 URL,拿回标准化的本地文件 -- 不管是哪个平台、什么内容类型,输出格式完全一致

Python Tests Coverage License CI


in  URL (douyin | xhs | wechat-oa | x) -- 内容页 or profile 页
out media files + metadata.json + content_item.json + text.txt + manifest.jsonl

fail unsupported platform     -> error + supported list
fail auth required (douyin)   -> "prepare cookies.json" instructions
fail sidecar not running (xhs)-> auto-install + auto-start XHS-Downloader
fail tool missing (x)         -> yt-dlp auto-installed via pip
fail CDN stream truncated     -> Range resume-on-partial (auto-reconnect until complete)
fail single item in batch     -> skip + continue, error logged in manifest
fail content deleted/private  -> skip + report in result

Adapters: douyin, xhs (via XHS-Downloader sidecar), wechat-oa, x (via yt-dlp)

示例输出

$ python3 -m content_downloader download "https://www.douyin.com/video/7621048932151414054" --cookies cookies.json

Downloaded: 7621048932151414054
  Platform : douyin
  Type     : video
  Location : output/douyin/102174692353/7621048932151414054

输出目录结构(每个平台一致):

output/douyin/102174692353/7621048932151414054/
├── media/
│   ├── video.mp4          # 去水印视频
│   └── cover.jpg          # 封面图
├── metadata.json          # 平台原始 API 数据(完整保留)
├── content_item.json      # 标准化 ContentItem(跨平台统一字段)
└── text.txt               # 纯文字内容(视频描述/推文文本/文章标题)

output/manifest.jsonl      # 全局索引,一行一个 item,append-only

content_item.json 示例:

{
  "platform": "douyin",
  "content_id": "7621048932151414054",
  "content_type": "video",
  "title": "AI 时代的内容创作方法论",
  "description": "分享我的内容创作工作流...",
  "author_id": "102174692353",
  "author_name": "慢学AI",
  "publish_time": "2026-03-30T01:44:29Z",
  "source_url": "https://www.douyin.com/video/7621048932151414054",
  "media_files": ["media/video.mp4"],
  "cover_file": "media/cover.jpg",
  "likes": 38000,
  "comments": 1220,
  "shares": 10000,
  "collects": 31000,
  "views": 520000
}

架构

                        ┌─────────────────────┐
                        │     CLI / API        │
                        │  content-downloader  │
                        └──────────┬──────────┘
                                   │
                        ┌──────────▼──────────┐
                        │    URL Router        │
                        │  auto-detect platform│
                        └──┬───┬───┬───┬──────┘
                           │   │   │   │
              ┌────────────┘   │   │   └────────────┐
              ▼                ▼   ▼                 ▼
        ┌──────────┐   ┌──────────┐ ┌──────────┐ ┌──────────┐
        │  Douyin   │   │   XHS    │ │ WeChat   │ │    X     │
        │ Adapter   │   │ Adapter  │ │ Adapter  │ │ Adapter  │
        │           │   │          │ │          │ │          │
        │ XBogus    │   │ HTTP API │ │ HTML GET │ │ yt-dlp   │
        │ signing   │   │ sidecar  │ │ + parse  │ │ subprocess│
        │     │     │   └────┬─────┘ └────┬─────┘ └────┬─────┘
        │     ▼     │
        │ Playwright│
        │ fallback  │
        └─────┬─────┘   ┌────┘            │             │
              │               │            │             │
              └───────────────┴────────┬───┴─────────────┘
                                       ▼
                            ┌──────────────────┐
                            │  Output Manager   │
                            │  + Manifest JSONL  │
                            └──────────────────┘
                                       ▼
                            ┌──────────────────┐
                            │  Standardized     │
                            │  ContentItem      │
                            │  + media files    │
                            └──────────────────┘

快速开始

# 1. 克隆仓库
git clone https://github.com/zinan92/content-downloader.git
cd content-downloader

# 2. 安装(自动安装所有依赖,包括 yt-dlp)
pip install -e .

# 3. 下载内容
# 公众号(零配置,直接可用)
python3 -m content_downloader download "https://mp.weixin.qq.com/s/xxx"

# 抖音(需要 cookies)
python3 -m content_downloader download "https://www.douyin.com/video/xxx" --cookies cookies.json

# 小红书(自动安装并启动 XHS-Downloader)
python3 -m content_downloader download "https://www.xiaohongshu.com/explore/xxx"

# X/Twitter(yt-dlp 已自动安装)
python3 -m content_downloader download "https://x.com/user/status/xxx"

# 创作者主页批量下载(抖音支持)
python3 -m content_downloader download "https://www.douyin.com/user/MS4wLjABAAAAxxx" --limit 5

# 查看支持的平台
python3 -m content_downloader platforms

功能一览

功能 说明 状态
抖音视频下载 去水印 + 封面 + metadata(API 签名 + Playwright fallback) 已完成
抖音图文下载 多图 + 封面 + metadata 已完成
抖音 Profile 批量 limit/since 增量下载 已完成
抖音短链接 v.douyin.com 自动解析 已完成
抖音 Cookie 采集 Playwright 浏览器登录 + 一键采集 已完成
小红书视频 通过 XHS-Downloader API 已完成
小红书图文 多图下载 + cover 已完成
小红书 sidecar 自管理 自动安装 + 启动 已完成
公众号文章 HTML + 图片 + 音频 ID 已完成
X 视频推文 视频 + 缩略图 + metadata 已完成
X 图片推文 多图全保留 已完成
X 纯文字推文 metadata + text.txt 已完成
统一 ContentItem 跨平台标准化数据模型 已完成
manifest.jsonl 全局 append-only 索引 已完成
CDN 断点续传 Range resume-on-partial,抖音 CDN 截断时自动重连 已完成
去重 已下载 content_id 自动跳过 已完成
text.txt 每条内容附带纯文本文件 已完成

各平台支持的内容类型

平台 视频 图文/多图 纯文字/文章 Profile 批量
抖音 去水印 MP4 多图 + cover N/A --limit N / --since DATE
小红书 MP4 多图 + cover N/A 暂不支持
公众号 N/A 文章 HTML + 内嵌图片 完整文章 暂不支持
X MP4 多图全保留 text.txt 暂不支持

技术栈

层级 技术 用途
语言 Python 3.11+ 核心
HTTP httpx 异步请求
数据模型 Pydantic v2 ContentItem 校验
CLI Click 命令行界面
抖音签名 XBogus / ABogus + gmssl API 请求签名
抖音 Fallback Playwright + Chromium 签名失败时浏览器提取
小红书 XHS-Downloader (sidecar) HTTP API 调用
X/Twitter yt-dlp 媒体下载
测试 pytest + pytest-asyncio 303 tests, 85% coverage

项目结构

content-downloader/
├── content_downloader/
│   ├── __init__.py
│   ├── __main__.py          # python -m content_downloader
│   ├── cli.py               # CLI: download / list / platforms
│   ├── models.py            # ContentItem, DownloadResult, DownloadError
│   ├── router.py            # URL -> platform 识别 + adapter 路由
│   ├── output.py            # 标准化目录结构写入
│   ├── manifest.py          # JSONL manifest 读写 (file-locked)
│   ├── tools/
│   │   └── cookie_fetcher.py # Playwright 浏览器 cookie 采集
│   └── adapters/
│       ├── base.py          # PlatformAdapter protocol
│       ├── fixture.py       # 测试用 fixture adapter
│       ├── douyin/          # 抖音 (XBogus 签名 + Playwright fallback)
│       ├── xhs/             # 小红书 (XHS-Downloader sidecar)
│       ├── wechat_oa/       # 公众号 (HTML 解析)
│       └── x/               # X/Twitter (yt-dlp)
├── tests/                   # 303 tests
├── cookies.json.example     # 抖音 cookies 模板
└── pyproject.toml

配置

抖音 Cookies

抖音需要浏览器 cookies。推荐使用内置的 cookie 采集工具(Playwright 浏览器自动采集):

# 一键采集(弹出浏览器,登录后按 Enter)
python3 -m content_downloader.tools.cookie_fetcher --output cookies.json

# 然后正常下载
python3 -m content_downloader download "https://www.douyin.com/video/xxx" --cookies cookies.json

Cookies 约 1-2 周有效,过期后重新运行 cookie_fetcher 即可。

需要先安装 Playwright:pip install playwright && playwright install chromium

Fallback 机制: 如果 API 签名被拒(返回 HTML 而非 JSON),自动启动 Playwright 浏览器提取视频数据。无需手动干预。

CDN 断点续传: 抖音 CDN 会在 1-8MB 后强制关闭 HTTP/2 stream(常见于 source=PackSourceEnum_AWEME_DETAIL 签名 URL)。下载器自动用 Range: bytes={pos}- 重连并追加写入,直到 Content-Length 满足。内置 stall 检测(连续 5 次无进展则放弃)和 40 次重连上限。

CLI 参数

参数 说明 默认值
--output-dir 输出目录 ./output
--cookies Cookies JSON 文件路径
--limit Profile 批量下载数量限制 0 (全部)
--since 增量下载起始日期 (YYYY-MM-DD)
--force 强制重新下载已存在的内容 False

For AI Agents

本节面向需要将此项目作为工具或依赖集成的 AI Agent。

Capability Contract

name: content-downloader
version: 0.1.0
capability:
  summary: Download content from any supported platform into standardized local files
  in: URL (douyin | xhs | wechat-oa | x) — content page or profile page
  out: media files + metadata.json + content_item.json + text.txt + manifest.jsonl
  fail:
    - "unsupported platform -> error + supported list"
    - "auth required (douyin) -> cookies instructions"
    - "sidecar unavailable (xhs) -> auto-install + auto-start"
    - "content deleted/private -> skip + report"
  adapters: [douyin, xhs, wechat_oa, x]
cli_command: python3 -m content_downloader
cli_args:
  - name: url
    type: string
    required: true
    description: Content or profile URL from any supported platform
cli_flags:
  - name: --output-dir
    type: string
    description: Output directory (default ./output)
  - name: --cookies
    type: string
    description: Path to cookies JSON file (required for douyin)
  - name: --limit
    type: integer
    description: Max items for profile download (0 = all)
  - name: --force
    type: boolean
    description: Force re-download even if already exists
install_command: pip install -e .
start_command: python3 -m content_downloader download <url>

Agent 调用示例

import subprocess
import json

# 下载抖音视频
result = subprocess.run(
    ["python3", "-m", "content_downloader", "download",
     "https://www.douyin.com/video/7621048932151414054",
     "--cookies", "cookies.json",
     "--output-dir", "./output"],
    capture_output=True, text=True,
)

# 读取标准化输出
content_item = json.loads(
    open("output/douyin/102174692353/7621048932151414054/content_item.json").read()
)
print(f"Title: {content_item['title']}")
print(f"Media: {content_item['media_files']}")
print(f"Likes: {content_item['likes']}")

# 读取全局 manifest
with open("output/manifest.jsonl") as f:
    for line in f:
        item = json.loads(line)
        print(f"{item['platform']}/{item['content_id']}: {item['title'][:50]}")

相关项目

项目 说明 链接
content-workbench 内容跨平台分发工作台 (content-downloader 的前端) zinan92/content-workbench
douyin-downloader-1 抖音 adapter 的能力来源 zinan92/douyin-downloader-1
XHS-Downloader 小红书 adapter 的 sidecar 后端 JoeanAmier/XHS-Downloader
intelligence 社交内容趋势研究引擎 (下游消费者) zinan92/intelligence
content-intelligence 内容洞察引擎 (下游消费者) zinan92/content-intelligence

License

MIT License. See LICENSE for details.

About

统一内容下载器。in URL (douyin/xhs/wechat/x) → out 标准化 media + metadata + manifest。CDN 断点续传 + Playwright fallback

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages