方案一:ftplib(FTP 協定)
from ftplib import FTP
import os
def ftp_download(host, user, password, remote_path, local_path, port=21):
with FTP() as ftp:
ftp.connect(host, port, timeout=30)
ftp.login(user, password)
ftp.set_pasv(True)
os.makedirs(os.path.dirname(local_path), exist_ok=True)
with open(local_path, 'wb') as f:
ftp.retrbinary(f'RETR {remote_path}', f.write, blocksize=8192)
print(f"FTP 下載完成: {local_path}")
方案二:urllib.request(標準庫 HTTP/HTTPS)
import urllib.request
from datetime import datetime
def http_download_urllib(url, local_path):
start = datetime.now()
print(f"開始下載: {start}")
req = urllib.request.Request(url, headers={'User-Agent': 'Mozilla/5.0'})
with urllib.request.urlopen(req, timeout=60) as resp, open(local_path, 'wb') as f:
# 可加入進度顯示
total = int(resp.headers.get('Content-Length', 0))
downloaded = 0
block_size = 8192
while True:
chunk = resp.read(block_size)
if not chunk:
break
f.write(chunk)
downloaded += len(chunk)
if total:
print(f"\r進度: {downloaded/total*100:.1f}%", end='')
elapsed = (datetime.now() - start).total_seconds()
print(f"\n下載完成,耗時 {elapsed:.1f} 秒")
方案三:requests(第三方庫,推薦生產環境)
import requests
from datetime import datetime
def http_download_requests(url, local_path):
start = datetime.now()
print(f"開始下載: {start}")
headers = {'User-Agent': 'Mozilla/5.0'}
with requests.get(url, headers=headers, stream=True, timeout=60) as resp:
resp.raise_for_status()
total = int(resp.headers.get('Content-Length', 0))
os.makedirs(os.path.dirname(local_path), exist_ok=True)
with open(local_path, 'wb') as f:
for chunk in resp.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
elapsed = (datetime.now() - start).total_seconds()
print(f"下載完成,耗時 {elapsed:.1f} 秒")
三方案比較
| 特性 | ftplib | urllib | requests |
| 協定 | FTP | HTTP/HTTPS | HTTP/HTTPS |
| 依賴 | 標準庫 | 標準庫 | 第三方 |
| 串流下載 | 支援 | 支援 | 優秀 |
| 進度顯示 | 手動實作 | 手動實作 | 簡單 |
| 重試/逾時控制 | 基本 | 基本 | 完整 |
| SSL/TLS 驗證 | FTP_TLS | 支援 | 完善 |
| 推薦場景 | FTP 伺服器 | 無第三方依賴環境 | 一般專案、生產環境 |
斷點續傳提示
- HTTP:使用
Range: bytes=start- 標頭,需伺服器支援
- FTP:使用
REST 指令設定起始位置
- 建議使用
requests + tqdm 進度條庫實作完整續傳邏輯