文章摘要
AI摘要生成

原因

网上很多搭建jsdelivr都是按照自己的服务器为中转缓存,实际上还是很依赖jsdelivr。

而国内很多jsdelivr的镜像站没有全部收录jsdelivr或者有延迟,有些包的依赖确实没有

先附上jsdelivr官网地址:https://www.jsdelivr.com/ 博客有很大一部分的静态资源来源于jsdelivr,但是jsdelivr在国内访问速度堪忧,需要将博客所用到的文件全部进行本地化,上传自己的cdn加速节点,下面附上下载代码,保证和jsdelivr一样的后缀路径。
美中不足的就是这个需要去jsdelivr官网找到对应的版本 手动复杂URL。

Snipaste_2025-12-20_14-47-31

使用方法

方法一:命令行参数

1
2
3
4
5
# 下载单个文件
python cdn.py https://fastly.jsdelivr.net/npm/colorthief@2.6.0/dist/color-thief.min.js

# 下载多个文件
python cdn.py https://fastly.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js https://fastly.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js

方法二:交互式输入

1
2
python cdn.py
# 然后按提示输入 URL,多个 URL 用空格分隔,输入空行结束

代码说明

默认情况下,文件会下载到用户桌面,并保持与 CDN 相同的目录结构。例如:

  • URL: https://fastly.jsdelivr.net/npm/colorthief@2.6.0/dist/color-thief.min.js
  • 保存路径: 桌面/npm/colorthief@2.6.0/dist/color-thief.min.js

完整代码

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import sys
import urllib.request
import urllib.parse
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed

# 获取桌面路径作为默认存储根目录
desktop_path = os.path.join(os.path.expanduser('~'), 'Desktop')
save_path = desktop_path

def download_file(url):
"""
下载文件到指定路径

Args:
url: 要下载的URL
"""
if not url:
print("未传入url")
return False

try:
# 解析URL,提取路径部分(去掉协议和域名)
# 例如: https://fastly.jsdelivr.net/npm/colorthief@2.6.0/dist/color-thief.min.js
# -> npm/colorthief@2.6.0/dist/color-thief.min.js
parsed_url = urllib.parse.urlparse(url)
url_path = parsed_url.path.lstrip('/')

if not url_path:
print(f"无法从URL中提取路径: {url}")
return False

# 获取文件名
file_name = os.path.basename(url_path)

# 构建保存路径(使用URL中的目录结构)
file_dir = os.path.dirname(url_path)
if file_dir:
final_save_path = os.path.join(save_path, file_dir)
else:
final_save_path = save_path

# 创建目录
Path(final_save_path).mkdir(parents=True, exist_ok=True)

# 构建完整文件路径
file_full_path = os.path.join(final_save_path, file_name)

# 下载文件
urllib.request.urlretrieve(url, file_full_path)

# 检查文件是否存在且有内容
if os.path.exists(file_full_path) and os.path.getsize(file_full_path) > 0:
print(f"已将{file_name}下载至{file_full_path}")
return True
else:
print(f"下载失败: {url}")
if os.path.exists(file_full_path):
os.remove(file_full_path)
return False

except Exception as e:
print(f"下载失败 {url}: {e}")
if 'file_full_path' in locals() and os.path.exists(file_full_path):
os.remove(file_full_path)
return False

def download_files(urls, max_workers=5):
"""
并发下载多个文件

Args:
urls: URL列表
max_workers: 最大并发数
"""
if not urls:
print("未传入url")
return

print(f"开始下载 {len(urls)} 个文件...")

with ThreadPoolExecutor(max_workers=max_workers) as executor:
# 提交所有下载任务
futures = {executor.submit(download_file, url): url for url in urls}

# 等待所有任务完成
for future in as_completed(futures):
url = futures[future]
try:
future.result()
except Exception as e:
print(f"下载出错 {url}: {e}")

print("所有下载任务完成")

if __name__ == '__main__':
# 解析命令行参数(支持多个URL)
urls = sys.argv[1:]

# 如果没有命令行参数,则从控制台输入
if len(urls) == 0:
print("请输入要下载的URL(多个URL请用空格分隔,输入空行结束):")
input_urls = []
while True:
try:
line = input().strip()
if not line:
break
# 按空格分割,支持一行输入多个URL
input_urls.extend(line.split())
except (EOFError, KeyboardInterrupt):
break

if not input_urls:
print("未输入URL")
print("用法1: python cdn.py <url1> [url2] [url3] ...")
print("用法2: python cdn.py(然后按提示输入URL)")
print(f"提示: 文件将下载到桌面: {save_path}")
sys.exit(1)

urls = input_urls

# 支持单个或多个URL下载
if len(urls) == 1:
download_file(urls[0])
else:
download_files(urls)

自定义配置

如果需要修改保存路径,可以修改脚本开头的 save_path 变量:

1
2
# 修改为自定义路径
save_path = "E:/cdn_files"

如果需要调整并发数,可以在调用 download_files 函数时传入 max_workers 参数,或者直接修改函数默认值。

  1. 确保 Python 版本 >= 3.6(使用了 pathlibconcurrent.futures
  2. 需要网络连接才能下载文件
  3. win电脑哈,mac或者linux自行修改脚本

执行记录

命令行模式交互如下图所示

image-20251220145634512

下载到桌面之后(该脚本是win电脑运行)我的是直接上传cdn节点

image-20251220145803413

后话

下载完成之后可以上传到项目文件本地化,希望这个脚本能够帮助到各位。

如果有更好的点子也可以在下方评论留言分享。