jiji262/douyin-downloaderPublic

A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. 抖音批量下载工具,去水印,支持视频、图集、合集、音乐(原声)。

Stars
11.2K
Forks
1.7K
Watchers
57
Open issues
28
Open PRs
12
Contributors
~1
Commits
91
Branches
1

PythonMITCreated May 25, 2023Last push 3d agoLatest release desktop-v0.11.5

Star history

since May 21, 2023
05K10KMay 2023Jun 2024Jul 2025Sep 2026
11.2K stars as of Sep 13, 2026, tracked back to May 21, 2023. Historical curve reconstructed from public GitHub event archives, calibrated to the current total.

Contribution activity

commits per day, last 52 weeks
SepOctNovDecJanFebMarAprMayJunJulAugSepMonWedFri2025-09-20: 0 commits2025-09-21: 0 commits2025-09-22: 0 commits2025-09-23: 0 commits2025-09-24: 0 commits2025-09-25: 0 commits2025-09-26: 0 commits2025-09-27: 0 commits2025-09-28: 0 commits2025-09-29: 0 commits2025-09-30: 0 commits2025-10-01: 0 commits2025-10-02: 0 commits2025-10-03: 0 commits2025-10-04: 0 commits2025-10-05: 0 commits2025-10-06: 0 commits2025-10-07: 0 commits2025-10-08: 0 commits2025-10-09: 0 commits2025-10-10: 0 commits2025-10-11: 0 commits2025-10-12: 0 commits2025-10-13: 0 commits2025-10-14: 0 commits2025-10-15: 0 commits2025-10-16: 0 commits2025-10-17: 0 commits2025-10-18: 0 commits2025-10-19: 0 commits2025-10-20: 0 commits2025-10-21: 0 commits2025-10-22: 0 commits2025-10-23: 0 commits2025-10-24: 0 commits2025-10-25: 0 commits2025-10-26: 0 commits2025-10-27: 0 commits2025-10-28: 0 commits2025-10-29: 0 commits2025-10-30: 0 commits2025-10-31: 0 commits2025-11-01: 0 commits2025-11-02: 0 commits2025-11-03: 0 commits2025-11-04: 0 commits2025-11-05: 0 commits2025-11-06: 0 commits2025-11-07: 0 commits2025-11-09: 0 commits2025-11-10: 0 commits2025-11-11: 0 commits2025-11-12: 0 commits2025-11-13: 0 commits2025-11-14: 0 commits2025-11-15: 0 commits2025-11-16: 0 commits2025-11-17: 0 commits2025-11-18: 0 commits2025-11-19: 0 commits2025-11-20: 0 commits2025-11-21: 0 commits2025-11-22: 0 commits2025-11-23: 0 commits2025-11-24: 0 commits2025-11-25: 0 commits2025-11-26: 0 commits2025-11-27: 0 commits2025-11-28: 0 commits2025-11-29: 0 commits2025-11-30: 0 commits2025-12-01: 0 commits2025-12-02: 0 commits2025-12-03: 0 commits2025-12-04: 0 commits2025-12-05: 0 commits2025-12-06: 0 commits2025-12-07: 0 commits2025-12-08: 0 commits2025-12-09: 0 commits2025-12-10: 0 commits2025-12-11: 0 commits2025-12-12: 0 commits2025-12-13: 0 commits2025-12-14: 0 commits2025-12-15: 0 commits2025-12-16: 0 commits2025-12-17: 0 commits2025-12-18: 0 commits2025-12-19: 0 commits2025-12-20: 0 commits2025-12-21: 0 commits2025-12-22: 0 commits2025-12-23: 0 commits2025-12-24: 0 commits2025-12-25: 0 commits2025-12-26: 0 commits2025-12-27: 0 commits2025-12-28: 0 commits2025-12-29: 0 commits2025-12-30: 0 commits2025-12-31: 0 commits2026-01-01: 0 commits2026-01-02: 0 commits2026-01-03: 0 commits2026-01-04: 0 commits2026-01-05: 0 commits2026-01-06: 0 commits2026-01-07: 0 commits2026-01-08: 0 commits2026-01-09: 0 commits2026-01-10: 0 commits2026-01-11: 0 commits2026-01-12: 0 commits2026-01-13: 0 commits2026-01-14: 0 commits2026-01-15: 0 commits2026-01-16: 0 commits2026-01-17: 0 commits2026-01-18: 0 commits2026-01-19: 0 commits2026-01-20: 0 commits2026-01-21: 0 commits2026-01-22: 0 commits2026-01-23: 0 commits2026-01-24: 0 commits2026-01-25: 0 commits2026-01-26: 0 commits2026-01-27: 0 commits2026-01-28: 0 commits2026-01-29: 0 commits2026-01-30: 0 commits2026-01-31: 0 commits2026-02-01: 0 commits2026-02-02: 0 commits2026-02-03: 0 commits2026-02-04: 0 commits2026-02-05: 0 commits2026-02-06: 0 commits2026-02-07: 0 commits2026-02-08: 0 commits2026-02-09: 0 commits2026-02-10: 0 commits2026-02-11: 0 commits2026-02-12: 0 commits2026-02-13: 0 commits2026-02-14: 0 commits2026-02-15: 0 commits2026-02-16: 0 commits2026-02-17: 0 commits2026-02-18: 0 commits2026-02-19: 0 commits2026-02-20: 0 commits2026-02-21: 0 commits2026-02-22: 0 commits2026-02-23: 0 commits2026-02-24: 1 commit2026-02-25: 0 commits2026-02-26: 0 commits2026-02-27: 0 commits2026-02-28: 0 commits2026-03-01: 0 commits2026-03-02: 0 commits2026-03-03: 0 commits2026-03-04: 0 commits2026-03-05: 0 commits2026-03-06: 0 commits2026-03-07: 0 commits2026-03-08: 0 commits2026-03-09: 0 commits2026-03-10: 0 commits2026-03-11: 0 commits2026-03-12: 0 commits2026-03-13: 0 commits2026-03-14: 0 commits2026-03-15: 0 commits2026-03-16: 0 commits2026-03-17: 0 commits2026-03-18: 0 commits2026-03-19: 0 commits2026-03-20: 0 commits2026-03-21: 0 commits2026-03-22: 0 commits2026-03-23: 0 commits2026-03-24: 0 commits2026-03-25: 0 commits2026-03-26: 0 commits2026-03-27: 0 commits2026-03-28: 0 commits2026-03-29: 0 commits2026-03-30: 0 commits2026-03-31: 0 commits2026-04-01: 0 commits2026-04-02: 0 commits2026-04-03: 0 commits2026-04-04: 0 commits2026-04-05: 0 commits2026-04-06: 0 commits2026-04-07: 0 commits2026-04-08: 0 commits2026-04-09: 0 commits2026-04-10: 0 commits2026-04-11: 0 commits2026-04-12: 0 commits2026-04-13: 0 commits2026-04-14: 0 commits2026-04-15: 0 commits2026-04-16: 0 commits2026-04-17: 0 commits2026-04-18: 0 commits2026-04-19: 0 commits2026-04-20: 0 commits2026-04-21: 0 commits2026-04-22: 0 commits2026-04-23: 0 commits2026-04-24: 0 commits2026-04-25: 0 commits2026-04-26: 0 commits2026-04-27: 0 commits2026-04-28: 0 commits2026-04-29: 0 commits2026-04-30: 0 commits2026-05-01: 0 commits2026-05-02: 0 commits2026-05-03: 0 commits2026-05-04: 0 commits2026-05-05: 0 commits2026-05-06: 0 commits2026-05-07: 0 commits2026-05-08: 0 commits2026-05-09: 0 commits2026-05-10: 0 commits2026-05-11: 0 commits2026-05-12: 0 commits2026-05-13: 0 commits2026-05-14: 0 commits2026-05-15: 0 commits2026-05-16: 0 commits2026-05-17: 0 commits2026-05-18: 0 commits2026-05-19: 0 commits2026-05-20: 0 commits2026-05-21: 0 commits2026-05-22: 0 commits2026-05-23: 0 commits2026-05-24: 0 commits2026-05-25: 0 commits2026-05-26: 0 commits2026-05-27: 0 commits2026-05-28: 0 commits2026-05-29: 0 commits2026-05-30: 0 commits2026-05-31: 0 commits2026-06-01: 0 commits2026-06-02: 0 commits2026-06-03: 0 commits2026-06-04: 0 commits2026-06-05: 0 commits2026-06-06: 0 commits2026-06-07: 0 commits2026-06-08: 0 commits2026-06-09: 0 commits2026-06-10: 0 commits2026-06-11: 0 commits2026-06-12: 0 commits2026-06-13: 0 commits2026-06-14: 0 commits2026-06-15: 0 commits2026-06-16: 0 commits2026-06-17: 0 commits2026-06-18: 0 commits2026-06-19: 0 commits2026-06-20: 0 commits2026-06-21: 0 commits2026-06-22: 0 commits2026-06-23: 1 commit2026-06-24: 0 commits2026-06-25: 12 commits2026-06-26: 0 commits2026-06-27: 0 commits2026-06-28: 0 commits2026-06-29: 1 commit2026-06-30: 0 commits2026-07-01: 1 commit2026-07-02: 6 commits2026-07-03: 3 commits2026-07-04: 1 commit2026-07-05: 0 commits2026-07-06: 2 commits2026-07-07: 0 commits2026-07-08: 1 commit2026-07-09: 1 commit2026-07-10: 0 commits2026-07-11: 1 commit2026-07-12: 1 commit2026-07-13: 1 commit2026-07-14: 0 commits2026-07-15: 0 commits2026-07-16: 1 commit2026-07-17: 1 commit2026-07-18: 0 commits2026-07-19: 0 commits2026-07-20: 2 commits2026-07-21: 2 commits2026-07-22: 0 commits2026-07-23: 0 commits2026-07-24: 2 commits2026-07-25: 1 commit2026-07-26: 0 commits2026-07-27: 2 commits2026-07-28: 2 commits2026-07-29: 0 commits2026-07-30: 1 commit2026-07-31: 0 commits2026-08-01: 0 commits2026-08-02: 4 commits2026-08-03: 0 commits2026-08-04: 0 commits2026-08-05: 1 commit2026-08-06: 0 commits2026-08-07: 1 commit2026-08-08: 0 commits2026-08-09: 0 commits2026-08-10: 0 commits2026-08-11: 0 commits2026-08-12: 0 commits2026-08-13: 0 commits2026-08-14: 0 commits2026-08-15: 2 commits2026-08-16: 1 commit2026-08-17: 3 commits2026-08-18: 0 commits2026-08-19: 0 commits2026-08-20: 0 commits2026-08-21: 2 commits2026-08-22: 2 commits2026-08-23: 0 commits2026-08-24: 0 commits2026-08-25: 15 commits2026-08-26: 1 commit2026-08-27: 0 commits2026-08-28: 2 commits2026-08-29: 3 commits2026-08-30: 0 commits2026-08-31: 0 commits2026-09-01: 0 commits2026-09-02: 1 commit2026-09-03: 0 commits2026-09-04: 0 commits2026-09-05: 0 commits2026-09-06: 1 commit2026-09-07: 0 commits2026-09-08: 0 commits2026-09-09: 0 commits2026-09-10: 0 commits2026-09-11: 0 commits2026-09-12: 0 commits2026-09-13: 0 commits2026-09-14: 0 commits2026-09-15: 0 commits2026-09-16: 0 commits2026-09-17: 0 commits2026-09-18: 0 commits2026-09-19: 0 commits
86 commits in the last yearLessMore

Signals and awards

derived from tracked data
  • Widely adopted

    11,205 stars

  • Permissive license

    MIT

  • Continuous integration

    Automated checks passing

README

main branch

Douyin Downloader V2.0

douyin-downloader

中文文档 (Chinese): [README.zh-CN.md](./README.zh-CN.md)

A practical Douyin downloader supporting videos, image-notes, collections, music, favorites collections, and profile batch downloads, with progress display, retries, SQLite deduplication, download integrity checks, and browser fallback support.

Desktop App (Douzy)

A desktop GUI built on the same backend, with dedicated workspaces for Douyin, TikTok, and YouTube. Paste a link to start, sync account content, follow every task, and manage downloaded works in a local archive.

  • Three platforms: Douyin videos, galleries, profiles, and collections; TikTok videos, photos, and profiles; YouTube videos, Shorts, channels, and playlists
  • Account content: sync Douyin following, favorites collections, collected series, and likes
  • Visual workflow: multi-link queue, task status and retry controls, local download archive, filters, and quick re-download

Beta: The desktop app is currently in closed beta. To try it, download the build from the Releases page.

Douyin link download TikTok download workspace YouTube workbench
Douzy Douyin link download workspace Douzy TikTok download workspace Douzy YouTube workbench
Paste a video, gallery, profile, or collection link and start in one click. Download public videos, photo posts, and profiles without signing in. Scan videos, Shorts, channels, and playlists, then configure video, MP3, or subtitle downloads.
Following management Favorites and likes Task Center
Douzy following management Douzy favorites and likes Douzy Task Center
Sync creators, filter new works, add notes, and download directly from the list. Browse collected videos, series, and liked works from the current Douyin account. Track job results, retry failures, and open output folders.

Screenshots were captured from the current desktop main build. Demonstration data is used for privacy.

Feature Overview

Supported

Feature Description
Single video download /video/{aweme_id}
Single image-note download /note/{note_id} and /gallery/{note_id}
Single collection download /collection/{mix_id} and /mix/{mix_id}
Single music download /music/{music_id} (prefers direct audio, fallback to first related aweme)
Short link parsing https://v.douyin.com/..., v.iesdouyin.com, bare hosts
Profile batch download /user/{sec_uid} + mode: [post, like, mix, music]
Logged-in favorites collections /user/self?showTab=favorite_collection + mode: [collect, collectmix]
No-watermark preferred Automatically selects watermark-free video source
Highest-quality selection Auto-picks highest bitrate from video.bit_rate ladder (video + live-photo)
Live stream recording live.douyin.com/{room_id} → FLV/HLS, preserves partial data on stream end
Comments collection Per-aweme comments (+ optional replies) saved as *_comments.json
Hot search + keyword search --hot-board [N] / --search "keyword" dumps to JSONL
REST API server mode --serve --serve-port 8000 (optional fastapi + uvicorn)
Notification push Bark / Telegram / Webhook on download completion
Extra assets Cover, music, avatar, JSON metadata
Video transcription Optional, using OpenAI Transcriptions API
Concurrent downloads Configurable concurrency, default 5
Retry with backoff Exponential backoff (1s, 2s, 5s)
Rate limiting Default 2 req/s
SQLite history Records download metadata; does not decide incremental skips
Incremental downloads Disk-based skip/redownload via increase.post/like/mix/music
Time filters start_time / end_time
Browser fallback Launches browser when pagination is blocked, manual CAPTCHA supported
Download integrity check Content-Length validation, auto-cleanup of incomplete files
Progress display Rich progress bars, supports progress.quiet_logs quiet mode
Docker deployment Dockerfile included
CI/CD GitHub Actions for testing and linting

Current Limitations

  • Browser fallback is fully validated for post; like/mix/music currently relies on API pagination
  • number.allmix / increase.allmix are retained as compatibility aliases and normalized to mix
  • collect / collectmix currently work for the account represented by the logged-in cookies only
  • collect / collectmix must be used alone and cannot be combined with post / like / mix / music
  • increase currently applies to post / like / mix / music; favorites collection modes do not support incremental stop
  • Live stream recording saves FLV natively; HLS sources only save the playlist (use ffmpeg for playable output)
  • The webcast room endpoint is not verified against every live scenario — treat as experimental

Quick Start

1) Requirements

  • Python 3.8+
  • macOS / Linux / Windows

2) Install dependencies

pip install -r requirements.txt

For browser fallback and automatic cookie capture:

pip install playwright
python -m playwright install chromium

3) Copy config file

cp config.example.yml config.yml

4) Get cookies (recommended: automatic)

python -m tools.cookie_fetcher --config config.yml

After logging into Douyin, return to the terminal and press Enter. Cookies will be written to your config automatically.

5) Docker deployment (optional)

docker build -t douyin-downloader .
docker run -v $(pwd)/config.yml:/app/config.yml -v $(pwd)/Downloaded:/app/Downloaded douyin-downloader

Minimal Working Config

link:
  - https://www.douyin.com/user/MS4wLjABAAAAxxxx

path: ./Downloaded/
mode:
  - post

number:
  post: 0
  collect: 0
  collectmix: 0

thread: 5
retry_times: 3
proxy: ""
database: true
database_path: dy_downloader.db

progress:
  quiet_logs: true

cookies:
  msToken: ""
  ttwid: YOUR_TTWID
  odin_tt: YOUR_ODIN_TT
  passport_csrf_token: YOUR_CSRF_TOKEN
  sid_guard: ""

browser_fallback:
  enabled: true
  headless: false
  max_scrolls: 240
  idle_rounds: 8
  wait_timeout_seconds: 600

transcript:
  enabled: false
  model: gpt-4o-mini-transcribe
  output_dir: ""
  response_formats: ["txt", "json"]
  api_url: https://api.openai.com/v1/audio/transcriptions
  api_key_env: OPENAI_API_KEY
  api_key: ""

Usage

Run with a config file

python run.py -c config.yml

Append CLI arguments

python run.py -c config.yml \
  -u "https://www.douyin.com/video/7604129988555574538" \
  -t 8 \
  -p ./Downloaded

Arguments

Argument Description
-u, --url Append download link(s), can be repeated
-c, --config Specify config file (default: config.yml)
-p, --path Specify download directory
-t, --thread Specify concurrency
--show-warnings Show warning/error logs
-v, --verbose Show info/warning/error logs
--hot-board [N] Fetch Douyin hot search board and write JSONL; optional top-N
--search KEYWORD Search videos by keyword, write JSONL
--search-max N Max items for --search (default 50)
--serve Run as REST API server (requires pip install fastapi uvicorn)
--serve-host HOST REST server listen host (default 127.0.0.1)
--serve-port PORT REST server listen port (default 8000)
--version Show version number

Typical Scenarios

Download one video

link:
  - https://www.douyin.com/video/7604129988555574538

Download one image-note

link:
  - https://www.douyin.com/note/7341234567890123456

Download a collection

link:
  - https://www.douyin.com/collection/7341234567890123456

Download a music track

link:
  - https://www.douyin.com/music/7341234567890123456

Batch download a creator's posts

link:
  - https://www.douyin.com/user/MS4wLjABAAAAxxxx
mode:
  - post
number:
  post: 50

Batch download a creator's liked posts

link:
  - https://www.douyin.com/user/MS4wLjABAAAAxxxx
mode:
  - like
number:
  like: 0    # 0 means download all

Download multiple modes at once

link:
  - https://www.douyin.com/user/MS4wLjABAAAAxxxx
mode:
  - post
  - like
  - mix
  - music

Cross-mode deduplication: the same aweme_id won't be downloaded twice across different modes.

Download logged-in favorites collection items

link:
  - https://www.douyin.com/user/self?showTab=favorite_collection
mode:
  - collect
number:
  collect: 0

Download logged-in collected mixes

link:
  - https://www.douyin.com/user/self?showTab=favorite_collection
mode:
  - collectmix
number:
  collectmix: 0

Record a live stream (experimental)

link:
  - https://live.douyin.com/123456789   # or /follow/live/{room_id}
live:
  max_duration_seconds: 3600   # 0 = record until broadcaster ends
  chunk_size: 65536
  idle_timeout_seconds: 30

The recorder saves an FLV file under Downloaded/{author}/live/ plus a *_room.json metadata snapshot. If the broadcaster ends the stream, network goes idle, or you Ctrl+C, any already-recorded bytes are preserved (the .tmp file is promoted to the final file).

Collect comments per aweme

comments:
  enabled: true
  include_replies: false   # true will fetch each comment's second-level replies (extra API calls)
  max_comments: 500        # 0 = no cap
  page_size: 20

Generates a {date}_{title}_{aweme_id}_comments.json next to the media file.

Dump the hot search board

python run.py --hot-board 30 -p ./Downloaded
# Output: ./Downloaded/hot_board/20260424_221530.jsonl

Search by keyword

python run.py --search "猫咪" --search-max 100 -p ./Downloaded
# Output: ./Downloaded/search/猫咪_20260424_221530.jsonl

Run as REST API server

pip install fastapi uvicorn       # one-time optional dep
python run.py --serve --serve-port 8000

Endpoints:

Method Path Description
POST /api/v1/download Submit {"url": "..."}, returns {job_id, status}
GET /api/v1/jobs/{job_id} Get a specific job's status/counts
GET /api/v1/jobs List recent jobs (TTL + capacity capped)
GET /api/v1/health Health probe

Finished jobs are pruned by TTL (default 24h) and max-jobs (default 500) — in-flight jobs are never pruned. Configure via server.max_jobs / server.job_ttl_seconds.

Send a notification on completion

notifications:
  enabled: true
  on_success: true
  on_failure: true
  providers:
    - type: bark
      url: https://api.day.app/YOUR_DEVICE_KEY
      sound: bell
    - type: telegram
      bot_token: "123456:ABC..."
      chat_id: "987654321"
    - type: webhook                 # works with 企业微信/飞书/钉钉 bot URLs too
      url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
      extra_body:
        msgtype: text

All enabled providers are notified in parallel; a failing provider never blocks the download flow.

Incremental download (disk-based)

increase:
  post: true

With true, the downloader skips an item only when its non-empty primary media already exists under the current download directory. Deleting the media file makes the next run download it again; SQLite history does not affect this decision.

Set a mode to false to redownload and atomically replace existing files within the current number/date/media filters.

Full crawl (no item limit)

number:
  post: 0

Optional Feature: Video Transcription (transcript)

Current behavior applies to video items only (image-note items do not generate transcripts).

1) Enable in config

transcript:
  enabled: true
  model: gpt-4o-mini-transcribe
  output_dir: ""        # empty: same folder as video; non-empty: mirrored to target dir
  response_formats:
    - txt
    - json
  api_key_env: OPENAI_API_KEY
  api_key: ""           # can be set directly, or via environment variable

Recommended to provide key through environment variable:

export OPENAI_API_KEY="sk-xxxx"

2) Output files

When enabled, it generates:

  • xxx.transcript.txt
  • xxx.transcript.json

If database: true, job status is also recorded in SQLite table transcript_job (success/failed/skipped).

Testing

Recommended:

python3 -m pytest -q

Plain pytest is also supported now:

pytest -q

Key Config Fields

Field Description
mode Supports post/like/mix/music; logged-in favorites mode additionally supports standalone collect/collectmix
number.post/like/mix/music/collect/collectmix Per-mode download limit, 0 = unlimited
increase.post/like/mix/music true: skip existing primary media on disk; false: redownload and overwrite current scope
start_time / end_time Time filter (format: YYYY-MM-DD)
folderstyle Create per-item subdirectories
browser_fallback.* Browser fallback for post when pagination is restricted
progress.quiet_logs Quiet logs during progress stage
transcript.* Optional transcription after video download
comments.* Per-aweme comments collection (opt-in)
live.* Live stream recording options (max_duration_seconds / chunk_size / idle_timeout_seconds)
notifications.* Bark/Telegram/Webhook push on completion
server.* REST API server tuning (max_jobs, job_ttl_seconds)
proxy Optional HTTP/HTTPS proxy setting
database Enable SQLite deduplication and history
database_path SQLite path, default is dy_downloader.db in the current working directory
thread Concurrent download count
retry_times Retry count on failure

Output Structure

Default with folderstyle: true and database_path: dy_downloader.db:

workspace/
├── config.yml
├── dy_downloader.db          # default location when database: true
└── Downloaded/
    ├── download_manifest.jsonl
    ├── hot_board/                # when --hot-board is used
    │   └── 20260424_221530.jsonl
    ├── search/                   # when --search is used
    │   └── 猫咪_20260424_221530.jsonl
    └── AuthorName/
        ├── post/
        │   └── 2024-02-07_Title_aweme_id/
        │       ├── ...mp4
        │       ├── ..._cover.jpg
        │       ├── ..._music.mp3
        │       ├── ..._data.json
        │       ├── ..._avatar.jpg
        │       ├── ..._comments.json    # when comments.enabled
        │       ├── ...transcript.txt
        │       └── ...transcript.json
        ├── like/
        │   └── ...
        ├── mix/
        │   └── ...
        ├── music/
        │   └── ...
        ├── collect/
        │   └── ...
        ├── collectmix/
        │   └── ...
        └── live/                 # when recording live streams
            └── 2026-04-24_2215_LiveTitle_RoomId/
                ├── ...flv
                └── ..._room.json

Re-downloading Content

The program uses a database record + local file dual check to decide whether to skip already-downloaded content. To force re-download, you need to clean up accordingly:

Re-download a specific item

# Delete local files (folder name contains the aweme_id)
rm -rf Downloaded/AuthorName/post/*_<aweme_id>/

# Delete database record
sqlite3 dy_downloader.db "DELETE FROM aweme WHERE aweme_id = '<aweme_id>';"

Re-download all items from a specific author

rm -rf Downloaded/AuthorName/
sqlite3 dy_downloader.db "DELETE FROM aweme WHERE author_name = 'AuthorName';"

Full reset (re-download everything)

rm -rf Downloaded/
rm dy_downloader.db

Note: Deleting only the database but keeping files will NOT trigger re-download — the program scans local filenames for aweme_id to detect existing downloads. Deleting only files but keeping the database WILL trigger re-download (the program treats "in DB but missing locally" as needing retry).

FAQ

1) Why do I only get around 20 posts?

This is a common pagination risk-control behavior. Make sure:

  • browser_fallback.enabled: true
  • browser_fallback.headless: false
  • complete verification manually in the browser popup, and do not close it too early

2) Why is the progress output noisy/repeated?

By default, progress.quiet_logs: true suppresses logs during progress stage.
Use --show-warnings or -v temporarily when debugging.

3) What if cookies are expired?

Run:

python -m tools.cookie_fetcher --config config.yml

4) Why are transcript files not generated?

Check in order:

  • whether transcript.enabled is true
  • whether downloaded items are videos (image-notes are not transcribed)
  • whether OPENAI_API_KEY (or transcript.api_key) is valid
  • whether response_formats includes txt or json

5) How to view download history?

sqlite3 dy_downloader.db "SELECT aweme_id, title, author_name, datetime(download_time, 'unixepoch', 'localtime') FROM aweme ORDER BY download_time DESC LIMIT 20;"

Community Group

qun

点击链接加入群聊【QQ群】:https://qm.qq.com/q/9xoNt8Wzv4

Disclaimer

This project is for technical research, learning, and personal data management only. Please use it legally and responsibly:

  • Do not use it to infringe others' privacy, copyright, or other legal rights
  • Do not use it for any illegal purpose
  • Users are solely responsible for all risks and liabilities arising from usage
  • If platform policies or interfaces change and features break, this is a normal technical risk

By continuing to use this project, you acknowledge and accept the statements above.

License

This project is licensed under the MIT License. See LICENSE for details.

Friendly Links

View on GitHub

Recent activity

commits and pull requests

Releases and announcements

10 total
  1. Desktop 0.11.5desktop-v0.11.5Sep 10, 20265.5K downloads

    Douzy Desktop 0.11.5 ## Downloads - **macOS Apple Silicon:** `Douzy-0.11.5-arm64.dmg` - **macOS Intel:** `Douzy-0.11.5.dmg` - **Windows x64:** `Douzy-Setup-0.11.5.exe` ## Installation - **本版未签名**,首次启动会被系统拦截,这是预期行为: - **macOS**:右键点击 Douzy.app 选「打开」,或先执行 `xattr -cr /Applications/Douzy.app`。 - **Windows**:SmartScreen 提示时选「更多信息 → 仍要运行」。 - Windows 新版为 per-machine 安装;旧版用户建议先卸载旧副本再安装。 - Telegram 需要用户自己的 `api_id` / `api_hash`,不填不影响其他平台。 - 标准版单链接任务入口无需邀请码;批量队列和高级 UI 流程仍需内测资格。 ## SHA-256 ``` 5905d89e9de55c1aef6c4d4e9eb86a9e883a749a0b1c6b6e8faf3c751fdab636 Douzy-0.11.5-arm64.dmg 14f97b6394057e984cdbcb1c0d936a2e243b13689d279a9920b24e32c687fbbf Douzy-0.11.5.dmg ae2a1544b506f787609a67cfb35d98753f866015ff18298cc0e8ef6f00f15871 Douzy-Setup-0.11.5.exe ```

  2. Desktop 0.11.4desktop-v0.11.4Sep 8, 20263.2K downloads

    Douzy Desktop 0.11.4 ## Downloads - **macOS Apple Silicon:** `Douzy-0.11.4-arm64.dmg` - **macOS Intel:** `Douzy-0.11.4.dmg` - **Windows x64:** `Douzy-Setup-0.11.4.exe` ## Installation - **本版未签名**,首次启动会被系统拦截,这是预期行为: - **macOS**:右键点击 Douzy.app 选「打开」,或先执行 `xattr -cr /Applications/Douzy.app`。 - **Windows**:SmartScreen 提示时选「更多信息 → 仍要运行」。 - Windows 新版为 per-machine 安装;旧版用户建议先卸载旧副本再安装。 - Telegram 需要用户自己的 `api_id` / `api_hash`,不填不影响其他平台。 - 标准版单链接任务入口无需邀请码;批量队列和高级 UI 流程仍需内测资格。 ## SHA-256 ``` e8f21ca47ed89ca1d9b3076371b0276443cc0ccc398a115f7657db87c7e79f87 Douzy-0.11.4-arm64.dmg f9afd48e75e162c17fa64f9d7700b62ee64bb855a90e6eead0a61f1a8e11c221 Douzy-0.11.4.dmg e9266018c1e5afae72d085d378bc3e07f5a73c0dd40162abdb8a41ef4929fa54 Douzy-Setup-0.11.4.exe ```

  3. Desktop 0.11.3desktop-v0.11.3Sep 4, 20263.8K downloads

    Douzy Desktop 0.11.3 ## Downloads - **macOS Apple Silicon:** `Douzy-0.11.3-arm64.dmg` - **macOS Intel:** `Douzy-0.11.3.dmg` - **Windows x64:** `Douzy-Setup-0.11.3.exe` ## Installation - **本版未签名**,首次启动会被系统拦截,这是预期行为: - **macOS**:右键点击 Douzy.app 选「打开」,或先执行 `xattr -cr /Applications/Douzy.app`。 - **Windows**:SmartScreen 提示时选「更多信息 → 仍要运行」。 - Windows 新版为 per-machine 安装;旧版用户建议先卸载旧副本再安装。 - Telegram 需要用户自己的 `api_id` / `api_hash`,不填不影响其他平台。 - 标准版单链接任务入口无需邀请码;批量队列和高级 UI 流程仍需内测资格。 ## SHA-256 ``` 40bb1f5b3565a25bdf96f19acd6136cf3235c30c8bc783a3e317a6e4dcbe72e7 Douzy-0.11.3-arm64.dmg 77f87e377d81fd9a4213e1630cb946989d1ced6f0fbb28e392963d1215f3ccd9 Douzy-0.11.3.dmg faebd887251120a04ec3ed4e19ae4422a464009b0b26f5e041619451fe105007 Douzy-Setup-0.11.3.exe ```

  4. Desktop 0.11.2desktop-v0.11.2Aug 30, 20265K downloads

    Douzy Desktop 0.11.2 ## Downloads - **macOS Apple Silicon:** `Douzy-0.11.2-arm64.dmg` - **macOS Intel:** `Douzy-0.11.2.dmg` - **Windows x64:** `Douzy-Setup-0.11.2.exe` ## Installation - **本版未签名**,首次启动会被系统拦截,这是预期行为: - **macOS**:右键点击 Douzy.app 选「打开」,或先执行 `xattr -cr /Applications/Douzy.app`。 - **Windows**:SmartScreen 提示时选「更多信息 → 仍要运行」。 - Windows 新版为 per-machine 安装;旧版用户建议先卸载旧副本再安装。 - Telegram 需要用户自己的 `api_id` / `api_hash`,不填不影响其他平台。 - 标准版单链接任务入口无需邀请码;批量队列和高级 UI 流程仍需内测资格。 ## SHA-256 ``` a8951b9e17745b07d9b69512d3cbdc516514df3601e811e864ab9ff125d20a1a Douzy-0.11.2-arm64.dmg 90e6902d486d2ffad838ab0fc2d12cb4a684bcd9fe5b7df1e696a4f325ecf89c Douzy-0.11.2.dmg 8947b004b65c947a57ea1955e1a74972b756ecc465f2a63bea0491e42893545e Douzy-Setup-0.11.2.exe ```

  5. Desktop 0.11.1desktop-v0.11.1Aug 28, 20261.8K downloads

    Douzy Desktop 0.11.1 ## Downloads - **macOS Apple Silicon:** `Douzy-0.11.1-arm64.dmg` - **macOS Intel:** `Douzy-0.11.1.dmg` - **Windows x64:** `Douzy-Setup-0.11.1.exe` ## Installation - **本版未签名**,首次启动会被系统拦截,这是预期行为: - **macOS**:右键点击 Douzy.app 选「打开」,或先执行 `xattr -cr /Applications/Douzy.app`。 - **Windows**:SmartScreen 提示时选「更多信息 → 仍要运行」。 - Windows 新版为 per-machine 安装;旧版用户建议先卸载旧副本再安装。 - Telegram 需要用户自己的 `api_id` / `api_hash`,不填不影响其他平台。 - 标准版单链接任务入口无需邀请码;批量队列和高级 UI 流程仍需内测资格。 ## SHA-256 ``` 1c5bf154d13c28fecd6e97a2d317588c04bf9f663b2737d06946ac2b2b90960a Douzy-0.11.1-arm64.dmg e319f67bdf1891e79ca23e3596d589e2a8fc74de34ce77e0f23238bdb41060d5 Douzy-0.11.1.dmg 0af09b5d5866d104aae38362cb949dd15ffe8c8f89e88cbb3c5bf2b11c1ce846 Douzy-Setup-0.11.1.exe ```

Commits per week

last 52 weeks
210Week of 2025-09-20: 0 commitsWeek of 2025-09-27: 0 commitsWeek of 2025-10-04: 0 commitsWeek of 2025-10-11: 0 commitsWeek of 2025-10-18: 0 commitsWeek of 2025-10-25: 0 commitsWeek of 2025-11-01: 0 commitsWeek of 2025-11-09: 0 commitsWeek of 2025-11-16: 0 commitsWeek of 2025-11-23: 0 commitsWeek of 2025-11-30: 0 commitsWeek of 2025-12-07: 0 commitsWeek of 2025-12-14: 0 commitsWeek of 2025-12-21: 0 commitsWeek of 2025-12-28: 0 commitsWeek of 2026-01-04: 0 commitsWeek of 2026-01-11: 0 commitsWeek of 2026-01-18: 0 commitsWeek of 2026-01-25: 0 commitsWeek of 2026-02-01: 0 commitsWeek of 2026-02-08: 0 commitsWeek of 2026-02-15: 0 commitsWeek of 2026-02-22: 1 commitsWeek of 2026-03-01: 0 commitsWeek of 2026-03-08: 0 commitsWeek of 2026-03-15: 0 commitsWeek of 2026-03-22: 0 commitsWeek of 2026-03-29: 0 commitsWeek of 2026-04-05: 0 commitsWeek of 2026-04-12: 0 commitsWeek of 2026-04-19: 0 commitsWeek of 2026-04-26: 0 commitsWeek of 2026-05-03: 0 commitsWeek of 2026-05-10: 0 commitsWeek of 2026-05-17: 0 commitsWeek of 2026-05-24: 0 commitsWeek of 2026-05-31: 0 commitsWeek of 2026-06-07: 0 commitsWeek of 2026-06-14: 0 commitsWeek of 2026-06-21: 13 commitsWeek of 2026-06-28: 12 commitsWeek of 2026-07-05: 5 commitsWeek of 2026-07-12: 4 commitsWeek of 2026-07-19: 7 commitsWeek of 2026-07-26: 5 commitsWeek of 2026-08-02: 6 commitsWeek of 2026-08-09: 2 commitsWeek of 2026-08-16: 8 commitsWeek of 2026-08-23: 21 commitsWeek of 2026-08-30: 1 commitsWeek of 2026-09-06: 1 commitsWeek of 2026-09-13: 0 commitsSep 20, 2025Sep 13, 2026
86 commits in the last 52 weeks.

When work happens

weekday and hour
SunMonTueWedThuFriSat036912151821Sun 0:00 — 0 commitsSun 1:00 — 0 commitsSun 2:00 — 0 commitsSun 3:00 — 0 commitsSun 4:00 — 0 commitsSun 5:00 — 0 commitsSun 6:00 — 0 commitsSun 7:00 — 0 commitsSun 8:00 — 0 commitsSun 9:00 — 0 commitsSun 10:00 — 0 commitsSun 11:00 — 0 commitsSun 12:00 — 2 commitsSun 13:00 — 0 commitsSun 14:00 — 0 commitsSun 15:00 — 0 commitsSun 16:00 — 0 commitsSun 17:00 — 0 commitsSun 18:00 — 0 commitsSun 19:00 — 0 commitsSun 20:00 — 0 commitsSun 21:00 — 3 commitsSun 22:00 — 1 commitsSun 23:00 — 1 commitsMon 0:00 — 0 commitsMon 1:00 — 0 commitsMon 2:00 — 0 commitsMon 3:00 — 0 commitsMon 4:00 — 0 commitsMon 5:00 — 0 commitsMon 6:00 — 0 commitsMon 7:00 — 0 commitsMon 8:00 — 0 commitsMon 9:00 — 2 commitsMon 10:00 — 1 commitsMon 11:00 — 0 commitsMon 12:00 — 0 commitsMon 13:00 — 0 commitsMon 14:00 — 0 commitsMon 15:00 — 2 commitsMon 16:00 — 0 commitsMon 17:00 — 1 commitsMon 18:00 — 1 commitsMon 19:00 — 1 commitsMon 20:00 — 1 commitsMon 21:00 — 0 commitsMon 22:00 — 2 commitsMon 23:00 — 0 commitsTue 0:00 — 0 commitsTue 1:00 — 0 commitsTue 2:00 — 0 commitsTue 3:00 — 0 commitsTue 4:00 — 0 commitsTue 5:00 — 0 commitsTue 6:00 — 0 commitsTue 7:00 — 0 commitsTue 8:00 — 0 commitsTue 9:00 — 0 commitsTue 10:00 — 0 commitsTue 11:00 — 0 commitsTue 12:00 — 0 commitsTue 13:00 — 2 commitsTue 14:00 — 1 commitsTue 15:00 — 8 commitsTue 16:00 — 6 commitsTue 17:00 — 1 commitsTue 18:00 — 1 commitsTue 19:00 — 0 commitsTue 20:00 — 1 commitsTue 21:00 — 0 commitsTue 22:00 — 1 commitsTue 23:00 — 0 commitsWed 0:00 — 0 commitsWed 1:00 — 0 commitsWed 2:00 — 0 commitsWed 3:00 — 0 commitsWed 4:00 — 0 commitsWed 5:00 — 0 commitsWed 6:00 — 0 commitsWed 7:00 — 0 commitsWed 8:00 — 0 commitsWed 9:00 — 0 commitsWed 10:00 — 1 commitsWed 11:00 — 0 commitsWed 12:00 — 0 commitsWed 13:00 — 0 commitsWed 14:00 — 1 commitsWed 15:00 — 0 commitsWed 16:00 — 0 commitsWed 17:00 — 0 commitsWed 18:00 — 1 commitsWed 19:00 — 0 commitsWed 20:00 — 0 commitsWed 21:00 — 1 commitsWed 22:00 — 0 commitsWed 23:00 — 1 commitsThu 0:00 — 0 commitsThu 1:00 — 0 commitsThu 2:00 — 0 commitsThu 3:00 — 0 commitsThu 4:00 — 0 commitsThu 5:00 — 0 commitsThu 6:00 — 0 commitsThu 7:00 — 0 commitsThu 8:00 — 0 commitsThu 9:00 — 1 commitsThu 10:00 — 0 commitsThu 11:00 — 0 commitsThu 12:00 — 0 commitsThu 13:00 — 2 commitsThu 14:00 — 0 commitsThu 15:00 — 0 commitsThu 16:00 — 1 commitsThu 17:00 — 1 commitsThu 18:00 — 2 commitsThu 19:00 — 1 commitsThu 20:00 — 11 commitsThu 21:00 — 2 commitsThu 22:00 — 0 commitsThu 23:00 — 0 commitsFri 0:00 — 0 commitsFri 1:00 — 0 commitsFri 2:00 — 0 commitsFri 3:00 — 0 commitsFri 4:00 — 0 commitsFri 5:00 — 0 commitsFri 6:00 — 0 commitsFri 7:00 — 0 commitsFri 8:00 — 0 commitsFri 9:00 — 0 commitsFri 10:00 — 2 commitsFri 11:00 — 3 commitsFri 12:00 — 1 commitsFri 13:00 — 0 commitsFri 14:00 — 1 commitsFri 15:00 — 0 commitsFri 16:00 — 0 commitsFri 17:00 — 0 commitsFri 18:00 — 0 commitsFri 19:00 — 0 commitsFri 20:00 — 2 commitsFri 21:00 — 0 commitsFri 22:00 — 0 commitsFri 23:00 — 2 commitsSat 0:00 — 0 commitsSat 1:00 — 0 commitsSat 2:00 — 0 commitsSat 3:00 — 0 commitsSat 4:00 — 0 commitsSat 5:00 — 0 commitsSat 6:00 — 0 commitsSat 7:00 — 0 commitsSat 8:00 — 0 commitsSat 9:00 — 0 commitsSat 10:00 — 1 commitsSat 11:00 — 0 commitsSat 12:00 — 0 commitsSat 13:00 — 1 commitsSat 14:00 — 1 commitsSat 15:00 — 0 commitsSat 16:00 — 0 commitsSat 17:00 — 0 commitsSat 18:00 — 2 commitsSat 19:00 — 0 commitsSat 20:00 — 0 commitsSat 21:00 — 2 commitsSat 22:00 — 1 commitsSat 23:00 — 2 commits
Commit volume by weekday and hour (UTC). Larger dots mean more commits.

Who is committing

last 52 weeks
Maintainer commits91 (100%)
Community commits0 (0%)

91 commits in total over the last year.

DateListRankStars gained
Sep 13, 2026daily#13+473