在某次課程中,有需多檔案需要手動新增目錄、下載,此腳本將根據提供的網址與儲存目錄,完整下載伺服器上的所有資源
已經下載的同名檔案將被忽略 此腳本無法判斷檔案是否有更新,請將目錄完全刪除再重新運行腳本
Demo Images
先安裝好第三方依賴,再設定 url 與 output_path 變數
pip install tqdm
腳本
1# 下載由 Python http-server 架設的完整檔案目錄
2# 需手動設定 url 與 output_path 變數
3# Author: XinShou
4
5from tqdm import tqdm # pip install tqdm
6from urllib.request import urlretrieve, urlopen
7from urllib.parse import unquote
8from urllib.error import URLError, HTTPError
9from queue import Queue
10import os
11import re
12
13url = "http://10.17.15.250:12345/"
14output_path = "./AIS3教材/"
15
16
17def fetch_url_content(target_url):
18 try:
19 with urlopen(target_url) as response:
20 return response.read().decode('utf-8')
21 except (URLError, HTTPError) as e:
22 print(f"Error fetching {target_url}: {e}")
23 return None
24
25
26def process_download_queue():
27 downloadQueue = Queue()
28 initial_content = fetch_url_content(url)
29 if initial_content:
30 for link in re.findall(r'<a href="([^"]+)">', initial_content):
31 downloadQueue.put(link)
32
33 while not downloadQueue.empty():
34 current = downloadQueue.get()
35
36 if current.endswith('/'):
37 directory_content = fetch_url_content(url + current)
38 if directory_content:
39 os.makedirs(os.path.dirname(os.path.join(output_path, current)), exist_ok=True)
40 for link in re.findall(r'<a href="([^"]+)">', directory_content):
41 downloadQueue.put(current + link)
42 else:
43 download_file(current)
44
45
46def download_file(relative_path):
47 full_path = os.path.join(output_path, unquote(relative_path))
48 if not os.path.exists(full_path):
49 with tqdm(unit='B', unit_scale=True, unit_divisor=1024, miniters=1, desc=unquote(relative_path)) as t:
50 urlretrieve(url + relative_path, full_path, reporthook=progress_hook(t))
51 else:
52 print("Already Exist, Skipped!")
53
54
55def progress_hook(t):
56 last_b = [0]
57
58 def update_to(b=1, bsize=1, tsize=None):
59 if tsize is not None:
60 t.total = tsize
61 t.update((b - last_b[0]) * bsize)
62 last_b[0] = b
63
64 return update_to
65
66
67if __name__ == "__main__":
68 process_download_queue()