一、先分清你的下载场景,对号入座
批量下载不是一个工具通吃所有场景。同样是"批量下载",下图片、下视频、下PDF、下种子文件、下GitHub仓库,用的工具完全不同。先把场景分清楚,再看工具。
| 场景 | 典型需求 | 推荐工具 | 难度 |
|---|---|---|---|
| 网页图片/视频 | 把某个网页或整个网站的所有图片扒下来 | 浏览器插件(ImageAssistant/DownThemAll) | ⭐ |
| URL列表文件 | Excel/CSV里有几百个下载链接,需要全部下载 | aria2c + 文本文件 / Python脚本 | ⭐⭐ |
| 种子/磁力链接 | 批量添加几百个磁力链接或种子文件 | aria2 RPC + WebUI / qBittorrent批量导入 | ⭐⭐ |
| 整站/目录下载 | 把某个目录或FTP下的文件全部拉下来 | wget 递归 / lftp mirror | ⭐⭐⭐ |
| GitHub仓库批量 | 批量克隆多个Git仓库或下载Release资源 | Git批量脚本 / gh CLI + Shell | ⭐⭐ |
| 网盘批量下载 | 百度网盘/阿里云盘/OneDrive批量拉文件 | 各自客户端 + 油猴脚本 / rclone | ⭐⭐⭐ |
| API数据采集 | 通过API接口批量下载数据(JSON/图片/文件) | Python aiohttp异步 + 令牌桶限速 | ⭐⭐⭐⭐ |
二、三个命令行神器,花10分钟学会就够用了
如果你只需要一个答案:aria2。它是目前开源社区公认最强的命令行下载工具,支持HTTP/HTTPS/FTP/BitTorrent/Metalink,多线程、断点续传、限速、RPC远程控制全都有。但如果你的场景不复杂,wget和curl也够用。
aria2:多线程下载的王者
一条命令就能从URL列表文件里批量下载所有文件,每个文件默认16线程(可调),断了自动续传:
# 从 urls.txt 批量下载,每文件16线程,最多5个并发任务aria2c -i urls.txt -x 16 -s 16 -j 5 -c --summary-interval=0# 带Cookie下载(登录后才能下载的页面)aria2c -i urls.txt --header="Cookie: session=xxxx" -x 16 -s 16# 限速2MB/s + 指定保存目录aria2c -i urls.txt -d ./downloads --max-download-limit=2M# 每个文件重命名为序号格式(001.mp4, 002.mp4...)aria2c -i urls.txt --auto-file-renaming=false --out="#1.mp4" --index-out="1"-x 每个服务器的连接数(默认1)-s 文件分段数(默认5)-j 同时下载的任务数(默认5)-c 断点续传-i 从文件读取URL列表--max-download-limit 整体下载速度上限--max-connection-per-server 同一服务器最大连接数(防封IP)wget:递归下载整站的老牌选手
aria2不能递归下载,wget可以。想把某个目录下所有文件(图片、PDF、HTML)全拉下来,wget一行搞定:
# 递归下载整个目录(深度1,只下载jpg和png)wget -r -l1 -nd -A "*.jpg,*.png" -P ./images https://example.com/gallery/# 镜像整个网站(静态资源)wget -mk -p -np --wait=1 --limit-rate=500K https://example.com/# 批量下载URL列表(每行一个URL的txt文件)wget -i urls.txt -P ./downloads -c-r 递归下载 -l 递归深度 -nd 不创建目录结构 -A 接受的文件后缀-mk 镜像+转换链接为本地 -p 下载页面所需资源 -np 不追溯父目录--wait=1 每次请求间隔1秒 --limit-rate 限速curl:轻量级单文件下载,适合嵌入脚本
curl不适合做"批量下载器",但它是最通用的HTTP客户端。适合在Shell脚本里配合循环做轻量批量下载,或者做下载前的URL验证:
# 从urls.txt逐行读取并下载while IFS= read -r url; dofilename=$(basename "$url")curl -L -C - -o "$filename" --retry 3 --retry-delay 5 "$url"done < urls.txt# 先HEAD检测文件大小,再决定要不要下载size=$(curl -sI "$url" | grep -i content-length | awk '{print $2}' | tr -d '\r')三、Python脚本方案:灵活度最高的选择
命令行工具解决不了这些情况:需要从数据库读取URL、需要根据规则动态拼接URL、需要处理登录态和Token刷新、下载完成后要自动重命名并按规则分文件夹、需要记录下载日志和失败重试策略。这时候上Python。

基础版:requests + 线程池
import requestsfrom concurrent.futures import ThreadPoolExecutor, as_completedfrom pathlib import Pathimport time# 读取CSV里的下载链接def load_urls(csv_path):import csvurls = []with open(csv_path, "r", encoding="utf-8") as f:for row in csv.DictReader(f):urls.append((row["url"], row.get("filename", "")))return urlsdef download_one(url, filename, save_dir, session):try:resp = session.get(url, timeout=30, stream=True)resp.raise_for_status()# 如果没有指定文件名,从URL或Content-Disposition提取if not filename:filename = url.split("/")[-1].split("?")[0]filepath = Path(save_dir) / filenamewith open(filepath, "wb") as f:for chunk in resp.iter_content(chunk_size=8192):f.write(chunk)return (True, url, filename, None)except Exception as e:return (False, url, filename, str(e))def batch_download(csv_path, save_dir, threads=10, delay=0.5):Path(save_dir).mkdir(parents=True, exist_ok=True)urls = load_urls(csv_path)failed = []session = requests.Session()session.headers.update({"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"})with ThreadPoolExecutor(max_workers=threads) as executor:futures = {}for i, (url, filename) in enumerate(urls):time.sleep(delay) # 请求间隔,防止被封future = executor.submit(download_one, url, filename, save_dir, session)futures[future] = (url, filename)for future in as_completed(futures):success, url, filename, error = future.result()if not success:failed.append((url, error))print(f"❌ 失败: {filename} - {error}")print(f"\n完成: 成功{len(urls) - len(failed)}/{len(urls)}, 失败 {len(failed)}")return failed# 使用示例if __name__ == "__main__":failed = batch_download("downloads.csv", "./downloaded", threads=10, delay=0.5)# 失败的重试一次if failed:print("\n重试失败的链接...")for url, error in failed:time.sleep(2)download_one(url, "", "./downloaded", session)进阶版:aiohttp异步 + 断点续传
当你需要下载几千甚至几万个文件时,线程池的效率瓶颈就很明显了。异步IO可以同时发起几百个请求,而且内存占用远低于多线程:
import asyncioimport aiohttpimport aiofilesfrom pathlib import Pathclass AsyncBatchDownloader:def __init__(self, save_dir, concurrency=50, retry=3):self.save_dir = Path(save_dir)self.save_dir.mkdir(parents=True, exist_ok=True)self.semaphore = asyncio.Semaphore(concurrency)self.retry = retryself.session = Noneself.stats = {"success": 0, "failed": 0, "skipped": 0}async def download(self, url, filename=""):if not filename:filename = url.split("/")[-1].split("?")[0]filepath = self.save_dir / filename# 文件已存在则跳过if filepath.exists():self.stats["skipped"] += 1returnasync with self.semaphore:for attempt in range(self.retry):try:async with self.session.get(url, timeout=60) as resp:resp.raise_for_status()async with aiofiles.open(filepath, "wb") as f:async for chunk in resp.content.iter_chunked(65536):await f.write(chunk)self.stats["success"] += 1returnexcept Exception as e:if attempt == self.retry - 1:self.stats["failed"] += 1print(f"❌ {filename}: {e}")await asyncio.sleep(2 ** attempt)async def batch_download(self, urls):headers = {"User-Agent": "Mozilla/5.0 (compatible; BatchDownloader/2.0)"}async with aiohttp.ClientSession(headers=headers) as self.session:tasks = [self.download(url) for url in urls]await asyncio.gather(*tasks)return self.stats# 使用async def main():urls = [f"https://example.com/files/{i}.pdf" for i in range(1000)]downloader = AsyncBatchDownloader("./batch_downloads", concurrency=50)stats = await downloader.batch_download(urls)print(stats)asyncio.run(main())实测下载1000个5KB的图片文件:线程池10线程 = 约48秒;异步50并发 = 约11秒。差距主要来自网络IO等待时间的利用效率,异步几乎不浪费等待时间。
四、浏览器插件:零门槛的图片批量下载
不是每个人都愿意打开命令行。如果你只是想在网页上批量下载图片或文件,浏览器插件是最省事的方案。
| 插件 | 核心能力 | 适合场景 | 免费 |
|---|---|---|---|
| ImageAssistant | 嗅探页面所有图片,按尺寸/类型筛选,一键批量下载。支持提取背景图、CSS中的图片、懒加载图片 | 网页图片素材收集、壁纸批量下载 | ✅ |
| DownThemAll! | 经典下载管理器,支持正则过滤链接、多线程、断点续传、队列管理 | 页面所有可下载文件(图片/PDF/压缩包) | ✅ |
| Fatkun | 一键提取当前页所有图片,缩略图预览,多标签页合并提取 | 电商商品图、图库批量下载 | ✅ |
| Chrono下载管理器 | 接管浏览器下载,支持批量暂停/继续、分类管理、下载历史搜索 | 替代浏览器自带下载管理器 | ✅ |
| Video DownloadHelper | 嗅探网页内嵌视频,支持YouTube/Vimeo等主流平台 | 网页视频下载 | 部分付费 |
· 浏览器内存会飙升,500张以上的图片下载建议分批操作,每批100-200张
· 部分网站对短时间内大量请求会返回429或直接ban IP,插件没法做复杂的反反爬策略,这种场景还是要上命令行或脚本
五、aria2的RPC模式:搭建自己的下载服务器
aria2最强大的功能不是命令行,而是RPC模式。开启RPC后,你可以在任何设备上通过Web界面远程添加下载任务,配合AriaNg这类WebUI使用体验不输迅雷。
# aria2 RPC 配置文件 ~/.aria2/aria2.confenable-rpc=truerpc-listen-all=truerpc-allow-origin-all=truerpc-secret=your_strong_token_hererpc-listen-port=6800# 下载设置max-concurrent-downloads=10max-connection-per-server=16split=16continue=truemax-overall-download-limit=0max-download-limit=0# 文件保存dir=/data/downloadsfile-allocation=falloc# BT/磁力链接设置enable-dht=truebt-enable-lpd=truebt-tracker=udp://tracker.opentrackr.org:1337/announce,udp://open.stealth.si:80/announce# 启动 aria2 RPC 服务(后台运行)aria2c --conf-path=~/.aria2/aria2.conf -D# 通过RPC添加下载任务(Python示例)import requests, jsondef aria2_add_uri(url, rpc_url="http://localhost:6800/jsonrpc", secret="your_token"):payload = {"jsonrpc": "2.0","method": "aria2.addUri","params": [f"token:{secret}", [url]],"id": "1"}resp = requests.post(rpc_url, json=payload)return resp.json()配好RPC后,用AriaNg(纯HTML前端,放到Nginx下就能用)连接,就是一个完整的远程下载管理平台。在公司电脑上添加任务,家里的NAS就开始下载,到家就能用。
六、断点续传和失败重试:决定批量下载成败的细节
批量下载1000个文件,不可能100%一次成功。网络波动、服务器限流、文件被删除、Cookie过期,任何一个都能让下载中断。工具选得再好,没有重试机制就是白搭。
| 工具 | 断点续传 | 失败重试 | 重试策略 |
|---|---|---|---|
| aria2 | ✅ 原生支持 | ✅ | --max-tries=N --retry-wait=N |
| wget | ✅ -c | ✅ | --tries=N --waitretry=N |
| curl | ✅ -C - | ✅ | --retry N --retry-delay N |
| Python脚本 | 需手动实现 | 需手动实现 | 指数退避、死信队列 |
| 浏览器插件 | ❌ 大多不支持 | ❌ 大多不支持 | 全靠手动 |
Python实现断点续传
def download_with_resume(url, filepath, session):filepath = Path(filepath)headers = {}if filepath.exists():# 已下载的大小downloaded = filepath.stat().st_sizeheaders["Range"] = f"bytes={downloaded}-"else:downloaded = 0resp = session.get(url, headers=headers, stream=True, timeout=60)# 206 = 服务器支持断点续传, 200 = 从头下载mode = "ab" if resp.status_code == 206 else "wb"with open(filepath, mode) as f:for chunk in resp.iter_content(chunk_size=65536):f.write(chunk)return filepath.stat().st_size不是所有服务器都支持Range。如果服务器返回200而不是206,说明不支持断点续传。大多数CDN和云存储(OSS/S3/COS)都支持,但某些小网站或动态生成的下载链接可能不支持。遇到不支持的情况,文件只能从头下载。
七、防封IP策略:批量下载的生存法则
不管用什么工具,短时间内对同一个域名发起几百个请求,大概率触发反爬机制。轻则返回429限速,重则直接封IP。下面是经过验证的几条策略:
1. 控制并发和间隔
同一域名的并发连接数不超过5,每个请求之间间隔200-500ms。aria2设置 --max-connection-per-server=5,Python用 time.sleep(random.uniform(0.2, 0.5))
2. 轮换User-Agent
准备10-20个真实浏览器的UA,每个请求随机选一个。不要用Python默认的UA,太容易被识别
3. Referer保持一致
下载图片或文件时,Referer设为目标网站首页或来源页面URL,不要留空,否则容易触发盗链检测
4. 代理池轮换
大规模下载时用代理IP轮换,aria2支持 --all-proxy 或每个任务单独指定代理。Python可以用 session.proxies 设置
5. 分时段下载
不要一次性跑完所有任务。1000个文件分3-5批,每批间隔5-10分钟,模拟正常用户行为
6. 尊重robots.txt
下载前先检查目标网站的robots.txt,如果明确Disallow了某个目录,就不要强行下载,这是最基本的互联网礼仪
八、云存储/网盘批量下载的特殊处理
云存储和网盘的批量下载和普通HTTP下载不太一样。百度网盘没有直接的下载链接,阿里云盘和OneDrive有API但有限速和配额。针对不同平台需要不同的策略:
阿里云OSS / 腾讯云COS
官方CLI工具(ossutil / coscli)最方便,支持sync命令同步整个Bucket,自带并发和断点续传:

# 阿里云OSS同步整个目录到本地ossutil sync oss://bucket-name/path/ ./local/ --parallel 10 --part-size 10485760# 腾讯云COS批量下载coscli sync cos://bucket-name/path/ ./local/ -rOneDrive / Google Drive
rclone是这俩的最佳搭档。配置一次后,支持sync、copy、mount等操作,自带重试和限速:
# rclone配置(一次性)rclone config# 批量同步OneDrive目录到本地rclone sync onedrive:/Documents ./local_docs --transfers 8 --progress百度网盘
不开放官方下载API,批量下载只能用客户端。有几个间接方案:
· 用油猴脚本(如"网盘直链下载助手")配合aria2 RPC调用
· 开SVIP后用客户端的"打包下载"功能
· 用alist挂载网盘后通过WebDAV批量下载
FTP/SFTP服务器
lftp的mirror命令是FTP批量下载的终极方案,自带多线程和续传:
# lftp mirror 镜像整个FTP目录lftp -e "mirror --parallel=10 --continue /remote/ /local/; quit" ftp://user:pass@host九、不同下载量级的工具组合建议
几十个文件
轻量场景
浏览器插件就够了。DownThemAll或ImageAssistant,3分钟搞定,不用写一行代码。记得下载前先预览筛选,别把不需要的小图标也下了。
几百个文件
中等规模
aria2命令行最合适。准备好URL列表txt文件,一行命令就跑完。记得设置并发数和请求间隔,别把对方服务器打崩。
几千到几万个
大规模
上Python异步脚本。线程池跑不动,aiohttp配合令牌桶限速,失败自动重试,断点续传,下载日志全部记录。需要代理池的话这时候也得上了。
持续/定时下载
长期运行
搭建aria2 RPC + AriaNg。在NAS或VPS上跑,WebUI管理任务,配合crontab定时下载。下载完自动通知,全自动无人值守。
十、文件下载后的批量处理
文件下载完不是终点。文件名乱码要重命名、不同格式要转换、压缩包要解压、重复文件要去重。下载只是第一步,后面的自动化处理同样重要:
# 批量重命名:去掉URL参数部分for f in *; do mv "$f" "$(echo "$f" | sed 's/?.*//')"; done# 批量解压所有zip文件到各自目录for zip in *.zip; do unzip "$zip" -d "${zip%.zip}"; done# 批量转换图片格式(ImageMagick)for img in *.png; do convert "$img" -quality 85 "${img%.png}.webp"; done# 删除0字节的空文件find ./downloads -type f -size 0 -deleteUC建站系统的批量资源下载管理
对于有大量网站需要管理素材资源的用户,UC建站系统内置了资源批量下载与管理模块:
支持CSV/Excel/API/数据库多种来源的URL列表导入,自动去重和有效性校验
基于aria2内核,自动调度并发数、限速策略、代理轮换,失败自动加入重试队列
图片自动压缩转WebP、文件自动重命名规则、压缩包自动解压、按站点/日期自动归档
下载的资源自动分发到对应站点的素材库目录,无需手动上传
实时显示每个下载任务的进度、速度、预计剩余时间,支持暂停/继续/取消单个任务
完整记录每次下载的来源URL、文件大小、耗时、MD5校验值,出问题时快速定位
最后说几句
文件批量下载这件事,工具选择比技术复杂。几十个文件用浏览器插件,几百个用aria2命令行,几千个上Python异步脚本,需要长期运行的搭aria2 RPC服务。核心原则就一条:下载量大就用异步,下载量小就图省事。中间地带aria2几乎通吃。
还有两个容易被忽略的点:一是下载前先用HEAD请求确认文件是否存在、大小是否合理,别下载了半个小时发现是个404页面;二是下载完检查文件完整性,尤其是大文件,对比一下Content-Length和实际文件大小,不一致就重新下载。这两个习惯养成,能少走很多弯路。
