高效批量下载文件:使用 Python 进行并行下载的实用教程

上篇不是提取出非常多的链接了吗?这篇博文就是用那提取的链接来高效批量下载图片资源

在处理大量文件下载任务时,效率和可靠性是两个至关重要的因素。无论你是在进行数据抓取、下载资源包还是管理大规模文件存储,确保文件下载的高效性和稳定性都是至关重要的。在这篇文章中,我们将介绍如何使用 Python 脚本实现高效的批量文件下载。我们将涵盖并行下载、错误处理、重试机制、进度显示等功能,帮助你轻松应对大规模文件下载任务。


1. 需求背景

在许多实际应用中,下载大量文件是常见的任务。比如:

  • 数据科学家:从公开数据源批量下载数据集。
  • 开发者:下载依赖包或资源文件。
  • 内容管理员:获取大量的图片或视频文件。

为了提高下载效率并确保文件完整性,我们需要一个能够处理多个文件下载的 Python 脚本,并具备错误处理、重试机制和进度显示功能。

2. 代码实现

以下是一个实现高效批量下载的 Python 脚本示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import requests
import os
from urllib.parse import urlparse
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor, as_completed
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

# 创建一个文件夹用于保存下载的文件
os.makedirs('downloads', exist_ok=True)

# 从文件中读取要下载的文件链接列表
def read_file_urls(file_path):
with open(file_path, 'r') as f:
return [line.strip() for line in f if line.strip()]

# 下载单个文件的函数(使用网站文件名作为本地文件名)
def download_file(url):
try:
# 解析文件名
parsed_url = urlparse(url)
filename = os.path.basename(parsed_url.path)

# 拼接本地保存路径
local_path = os.path.join('downloads', filename)

print(f'Downloading {url}...')

# 创建会话并挂载适配器
session = requests.Session()
retry_strategy = Retry(
total=3,
status_forcelist=[429, 500, 502, 503, 504],
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)

response = session.get(url, stream=True)
total_size = int(response.headers.get('content-length', 0))

# 写入文件
with open(local_path, 'wb') as f:
with tqdm(total=total_size, unit='B', unit_scale=True, desc=os.path.basename(local_path), ncols=80) as pbar:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
f.write(chunk)
pbar.update(len(chunk))

print(f'Saved as {local_path}')
return local_path
except Exception as e:
print(f'Failed to download {url}. Error: {str(e)}')
return None

# 批量下载函数(并行、带错误处理、重试、缓存和断点续传)
def download_files(file_urls):
with ThreadPoolExecutor(max_workers=5) as executor: # 控制并发数
futures = [executor.submit(download_file, url) for url in file_urls]
for future in as_completed(futures):
result = future.result()
if result:
print(f'Downloaded: {result}')

# 调用读取文件链接和并行下载函数
file_urls = read_file_urls('links.txt')
download_files(file_urls)

3. 代码解析

文件下载与保存

  • download_file 函数负责下载单个文件。我们使用 requests 模块发送 GET 请求,并利用 tqdm 模块显示下载进度。
  • os.path.basename(urlparse(url).path) 提取文件名作为本地保存文件的名称。
  • 文件的下载过程中,通过检查响应头的 content-length 实现进度条的实时更新,并且将文件写入本地存储。

错误处理与重试机制

  • 使用 Retry 类配置重试策略,当遇到 429(请求过多)、500(服务器错误)等 HTTP 状态码时,将自动重试最多 3 次。

并行下载

  • ThreadPoolExecutor 实现了多线程并发下载,通过控制最大并发数(max_workers=5)来优化下载速度。

从文件中读取 URL 列表

  • read_file_urls 函数从指定的文本文件中读取要下载的文件链接。

4. 运行脚本

要运行这个脚本,请按照以下步骤操作:

  1. 将脚本保存为 download_files.py

  2. 确保在当前目录下有一个名为 links.txt 的文件,其中包含要下载的文件链接,每行一个。

  3. 打开终端(或命令提示符),导航到保存脚本的目录。

  4. 执行脚本:

    1
    python download_files.py
  5. 脚本将开始下载 links.txt 文件中列出的所有文件,并将它们保存在 downloads 文件夹中。

5. 总结

通过上述代码和教程,你可以轻松地实现高效的批量文件下载。无论你需要下载多少文件,这个脚本都能够处理并行下载、错误处理、重试机制和进度显示等功能,确保下载过程的顺利进行。希望这个教程对你有所帮助,如果你有任何问题或改进建议,请在评论中留言,我们非常期待你的反馈!