Skip to main content

lianzz-downloader

通过 HTTP Range 实现的 Python 多线程分段下载器。一个文件被切成 N 段,每段由独立线程并发拉取,最后就地写入同一文件 —— 这是 IDM、aria2、axel 的核心思路。

实测在本地服务器(每连接限速 2 MB/s)下,下载 80 MB 文件:

线程数 耗时 均速 加速比
1 41s 1.93 MB/s 1.00x
8 5.3s 15.2 MB/s 7.85x
16 2.8s 28.3 MB/s 14.6x

1 线程和 8 线程下载的同一文件 SHA-1 完全一致,验证分片写入正确无损坏。

功能

  • ✅ HTTP Range 多线程分段下载
  • ✅ HEAD 探测 + Range GET 探测双路径
  • ✅ 失败自动重试(指数退避,最多 5 次)
  • ✅ 全局令牌桶限速
  • ✅ 暂停 / 恢复 / 取消
  • ✅ 不支持 Range 时自动降级为单线程流式下载
  • ✅ 实时进度回调(速度、ETA、活跃线程数)
  • ✅ 命令行 + Tkinter 简洁 GUI
  • ✅ 临时文件预分配,避免磁盘碎片

安装

从 PyPI 安装(推荐):

pip install lianzz-downloader

从源码安装:

git clone <repo-url>
cd lianzz-downloader
pip install .

依赖只有 requests。

用法

命令行

# 基本
lianzz-downloader https://nodejs.org/dist/v20.10.0/node-v20.10.0-win-x64.zip

# 或
python -m lianzz_downloader https://nodejs.org/dist/v20.10.0/node-v20.10.0-win-x64.zip

# 指定参数
lianzz-downloader <URL> -o my.zip -n 16 --speed 2048 --header "Authorization: Bearer xxx"

参数:

参数 说明 默认
url 下载链接(位置参数) —
-o / --output 保存路径 URL 末段
-n / --threads 线程数 1-32 8
--chunk 单次读取字节数 64 KB
--speed 限速(字节/秒),0 = 不限 0
--retries 单分片重试次数 5
--no-resume 禁用断点续传 —
--header 自定义请求头(可多次) —
-v 调试日志 —

图形界面

lianzz-downloader-gui

或:

python -m lianzz_downloader.gui

简洁的 Tkinter 界面:URL、保存路径、线程数、限速、进度条、暂停 / 取消。

作为库使用

from lianzz_downloader.core import SegmentedDownloader, DownloadConfig

def on_progress(p):
    print(f"{p.percent:5.1f}%  {p.format_speed()}  ETA {p.format_eta()}")

cfg = DownloadConfig(
    url="https://example.com/big.zip",
    output_path="big.zip",
    threads=8,
    speed_limit=0,            # 0 = 不限速
    headers={"Referer": "..."},
)

dl = SegmentedDownloader(cfg, on_progress)
# dl.pause() / dl.resume() / dl.cancel()  随时控制
path = dl.run()

运行测试

# 1) 启动本地测试服务器(每连接限速 2MB/s,生成 80MB 文件)
python examples/test_server.py 18080 2048 80

# 2) 另开终端跑对比测试
python examples/benchmark_local.py

# 3) 功能测试(暂停/恢复/限速)
python examples/test_features.py

实现要点

  • HTTP Range 请求:每个分片发独立 Range: bytes=A-B 请求,写入同一 .part 文件的对应偏移
  • 线程池:concurrent.futures.ThreadPoolExecutor,每分片一个 worker
  • 预分配:os.posix_fallocate 占用整块空间,下载时直接 seek+write,避免磁盘碎片
  • 断点续传:每个分片维护 downloaded 偏移;网络断开后,从中断偏移续传
  • HEAD 探测:先 HEAD 拿 Content-Length 与 Accept-Ranges;若 HEAD 被拦截则用 Range: bytes=0-0 做 GET 探测
  • 降级路径:服务器忽略 Range 时(返回 200)自动改用 iter_content 流式下载
  • 限速:令牌桶算法,4 线程共享 1 个桶时,总速率精确等于设定值
  • 进度上报:所有分片共享一个 _downloaded_total(Lock 保护),主线程每 250 ms 采样计算瞬时速度与 ETA

目录结构

lianzz-downloader/
├── lianzz_downloader/
│   ├── __init__.py
│   ├── __main__.py     # python -m lianzz_downloader 入口
│   ├── core.py         # 分段下载核心引擎
│   ├── cli.py          # argparse CLI
│   └── gui.py          # Tkinter GUI
├── examples/
│   ├── test_server.py     # 本地测试 HTTP 服务器
│   ├── benchmark.py       # 外部源对比
│   ├── benchmark_local.py # 本地源对比
│   └── test_features.py   # 暂停/限速/线程数功能测试
├── LICENSE
├── pyproject.toml
└── README.md

License

MIT

Metadata

Release files for lianzz-downloader 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lianzz-downloader 1.0.0
File Size Uploaded Provenance
lianzz_downloader-1.0.0.tar.gz 16.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for lianzz-downloader 1.0.0
File Interpreter ABI Platform
lianzz_downloader-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.6 kB

Release files / lianzz_downloader-1.0.0.tar.gz

Download URL lianzz_downloader-1.0.0.tar.gz
Size 16.0 kB
Tags Source
SHA-256 checksum
How to use checksums
20434f66927357779df8f60f6a655f60e1583e1463351d8ee27276c509334f28
BLAKE2b-256 checksum
How to use checksums
29517ab23b2ba3aaa90745eabbfc33e3a19256971d6155fadd9e05dd88aa41ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / lianzz_downloader-1.0.0-py3-none-any.whl

Download URL lianzz_downloader-1.0.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7c23c86b293f08fbc3dfcd138bce9341db35d69ee98cc9df2d61e530c379b35f
BLAKE2b-256 checksum
How to use checksums
ea79ab524e9f11b7972b2e64026c3c9ce586954a22026ce892dd92b3ff096cd6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Security for lianzz-downloader 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page