如何用Python的wget库实现Linux中wget -c的断点续传与防重复下载?
实现Python中类似
wget -c的续传+避免重复下载功能 我之前也踩过这个坑!Python第三方库wget(就是pip install wget安装的那个)功能比较基础,确实没有直接对应Linux命令wget -c的参数。不过我们可以用更灵活的工具来实现相同的效果——要么用requests库(更简洁),要么用Python标准库urllib(不需要额外安装依赖)。
方法一:用requests库实现(推荐)
这个方法逻辑清晰,代码简洁,还能轻松处理HTTP头和状态码:
import requests import os def resume_download(url, save_path): # 检查本地文件是否存在,获取已下载大小 if os.path.exists(save_path): downloaded_size = os.path.getsize(save_path) # 构建Range请求头,告诉服务器从已下载位置继续发送数据 headers = {'Range': f'bytes={downloaded_size}-'} response = requests.get(url, headers=headers, stream=True) # 处理响应状态码 if response.status_code == 416: print("文件已经完全下载,无需续传") return elif response.status_code != 206: print(f"续传请求失败(状态码:{response.status_code}),将从头开始下载") response = requests.get(url, stream=True) downloaded_size = 0 else: # 文件不存在,直接从头下载 response = requests.get(url, stream=True) downloaded_size = 0 # 计算总文件大小 total_size = int(response.headers.get('content-length', 0)) + downloaded_size # 以追加模式写入文件 with open(save_path, 'ab') as f: for chunk in response.iter_content(chunk_size=1024*1024): # 1MB块大小 if chunk: f.write(chunk) downloaded_size += len(chunk) # 可选:打印实时下载进度 print(f"\r已下载:{downloaded_size}/{total_size} bytes", end="") print("\n下载完成!") # 使用示例 resume_download("https://example.com/your_large_file.zip", "./local_file.zip")
方法二:用标准库urllib实现(无额外依赖)
如果不想安装第三方库,用Python自带的urllib也能实现:
import urllib.request import os def resume_download_urllib(url, save_path): downloaded_size = 0 headers = {} if os.path.exists(save_path): downloaded_size = os.path.getsize(save_path) headers['Range'] = f'bytes={downloaded_size}-' try: req = urllib.request.Request(url, headers=headers) with urllib.request.urlopen(req) as response: # 处理状态码 if response.getcode() == 416: print("文件已经完全下载,无需操作") return elif response.getcode() != 206 and downloaded_size > 0: print("续传失败,将重新下载整个文件") req = urllib.request.Request(url) response = urllib.request.urlopen(req) downloaded_size = 0 total_size = int(response.headers.get('Content-Length', 0)) + downloaded_size with open(save_path, 'ab') as f: while True: chunk = response.read(1024*1024) # 1MB块读取 if not chunk: break f.write(chunk) downloaded_size += len(chunk) print(f"\r已下载:{downloaded_size}/{total_size} bytes", end="") print("\n下载完成!") except Exception as e: print(f"下载过程出错:{str(e)}") # 使用示例 resume_download_urllib("https://example.com/your_large_file.zip", "./local_file.zip")
为什么Python的wget库做不到?
第三方wget库的核心功能比较简单,它的download()函数默认会覆盖已存在的文件,或者通过out参数指定保存路径,但没有实现基于HTTP Range头的续传逻辑,所以没法直接实现wget -c的效果。上面两种方法都是手动实现了续传的核心逻辑——检查本地文件大小、发送Range请求、追加写入内容,完美复刻了wget -c的功能。
内容的提问来源于stack exchange,提问作者DevTar




