jsdelivr cdn 切换到阿里云自建加速

问题简述

本站使用的主题有相当一部分的资源是挂在 jsdelivr 上的,由于网络原因需要更换源。通过 VSCode 打开主题目录搜索了一下,存在 170 多个引用,我整合了一些 python 脚本实现了快速迁移

解决方案

Chrome 插件 Clear Site Data 可以快速清除当前站点的缓存,调试时是必备之选

主要步骤如下:

  • 开启阿里 OSS 和 CDN 服务
  • 提取主题所有 jsdelivr 引用
  • 批量下载 jsdelivr 引用 到本地
  • 上传文件到阿里 OSS
  • 修改主题相关引用的域名

提取 jsdelivr 引用

  • vscode 打开主题目录,可以 clone 主题到本地修改再上传或使用 VSCode SSH Remote 直接修改
  • 全局搜索 jsdelivr,选择 “ 在编辑器中打开 ”,按下 Ctrl + S 保存搜索记录到本地,命名为 links.txt
  • 新建 python 脚本,修改 TAG1, TAG2 两处,TAG1 是脚本要搜索的目录,新建一个空白文件夹,把上面的 links.txt 放进来;TAG2 是结果导出位置。这个脚本来自 csdn ayesawyer

    import re
    import os
    # TAG 1
    path=r'C:\\Users\\Nickel\\Desktop\\temp'
    file_path=[]
    for filename in os.listdir(path):
        file_path.append((os.path.join(path,filename)))
    print (file_path)
    for adress in file_path:  
        file_object=open(adress,'rb')
        lines = file_object.readlines( )
        file_object.close()
        new_lines=[] 
        for x in lines: 
            new_x = x.split( )
            for i in new_x:
                try:      
                    data=i;
                    data = data.decode('utf-8')
                    match_obj=re.search(r"https://.*",data)  
                    if match_obj:  
                        new_lines.append(match_obj.group())  
                except:
                    continue
    final=new_lines
    # TAG 2
    file_2=open(r'D:\\result.txt','w+')
    for x in final:
        for k in range(len(x)):
            if (x[k]=="\""):
                x=x[:k]
                break;
        file_2.write(x)  
        file_2.write('\n')  
    file_2.close()
  1. 上面导出的结果文件还需要二次简单修改

    • 末尾可能会有单引号,逗号
    • 不包括 //cdn.hello.com/xxx 无协议头的链接
    • 不包括 http 协议链接

批量下载

由于原 jsdelivr cdn 的链接是有目录层次的,所以批量下载时的脚本要照顾到这一点

首先新建如下内容的 Python 脚本,这个脚本来自 csdn DarkAthena

import urllib.request
import requests
import re, os
# 基于 https://zhuanlan.zhihu.com/p/62876301 修改

def get_file(url):
    '''
    递归下载网站的文件
    :param url:
    :return:
    '''

    if isFile(url):
        print(url)
        try:
            download(url)
        except:
            pass
    else:
        urls = get_url(url)
        for u in urls:
            get_file(u)

def isFile(url):
    '''
    判断一个链接是否是文件
    :param url:
    :return:
    '''
    if url.endswith('/'):
        return False
    else:
        return True

hander=urllib.request.ProxyHandler({'http':'127.0.0.1:10809'})
opener=urllib.request.build_opener(hander)

def download(url):
    '''
    :param url:文件链接
    :return: 下载文件,自动创建目录
    '''
    full_name = url.split('//')[-1]
    filename = full_name.split('/')[-1]
    dirname = "/".join(full_name.split('/')[:-1])
    if os.path.exists(dirname):
        pass
    else:
        os.makedirs(dirname, exist_ok=True)
    urllib.request.urlretrieve(url, full_name)

def get_url(base_url):
    '''
    :param base_url:给定一个网址
    :return: 获取给定网址中的所有链接
    '''
    text = ''
    try:
        text = requests.get(base_url).text
    except Exception as e:
        print("error - > ",base_url,e)
        pass
    reg = '<a href="(.*)">.*</a>'
    urls = [base_url + url for url in re.findall(reg, text) if url != '../']
    return urls

if __name__ == '__main__':
    with open('links.txt', 'r') as f:
        lines = f.readlines()
        url_list = []
        for line in lines:
            get_file(line.strip('\n'))

我在它的基础上添加了代理,因为不加代理没办法下载下来的

hander=urllib.request.ProxyHandler({'http':'127.0.0.1:10809'})
opener=urllib.request.build_opener(hander)

然后安装 requests 模块,通过 pip 或 conda 都可以

pip install requests
# 或者
conda install requests

执行这个脚本会在当前目录下载 links.txt 中的链接,记得修改上述脚本中 links.txt 的路径

最后几步

  1. 打开阿里云 OSS 控制台,选择上传目录,等待上传完毕
  2. 测试 cdn 链接是否可用
  3. 通过 VSCode 全局查找功能,批量修改 jsdelivr.net 域名为你的 cdn 加速域名