CMIP6数据传统方式下载的问题
CMIP6数据一般是利用sh脚本下载,这种下载方式利用的是传统的wget下载方式,其速度取决于个人网速和服务器的响应速度.最近下载CMIP6数据不同节点(不同节点)的下载速度相比之前都比较慢,平均只有几百kb/s。对于CMIP6庞大的数据量而言,这速度实在比较慢。因此,我写了一点并行下载的程序仅供个人参考和记录。
1、mgwet并行下载
mwget 是一个多线程命令行下载工具,旨在提高大文件或多个文件下载时的效率与可靠性。它支持断点续传、批量下载、限速控制以及 HTTP、HTTPS 等常见协议,并可通过配置文件灵活定制下载行为。相比传统的 wget,mwget 在下载速度和资源管理方面表现更加优异,特别适合需要高效数据抓取或自动化任务的场景。
前提安装mwget
利用mwget实现CMIP6数据的并行下载:
#导入库文件
import glob
import os
import argparse
import subprocess
import re
import hashlib
from pathlib import Path
import sys
#创建解析器
parser=argparse.ArgumentParser()
parser.add_argument('filename',type=str,help='文件名')
parser.add_argument('n',type=int,help='设置下载的线程数,默认开4个线程')
parser.add_argument('dirout',type=str,help='保存数据的目录')
args=parser.parse_args()
#读取哈希值
def extract_sha256(file_path):
with open(file_path, 'r') as file:
content = file.read()
# 匹配 'SHA256' 后跟任意空白,然后捕获单引号或双引号内的64位哈希
matches = re.findall(r"'SHA256'\s*['\"]([a-fA-F0-9]{64})['\"]", content)
return matches
#读取下载文件的链接
def CMIP6_download_links(file_path):
with open(args.filename,'r',encoding='utf-8') as file:
content = file.read()
#定义正则表达式模式
urls_pattern = r'(https?://[^\s]+?nc\b)'
download_links = re.findall(urls_pattern,content)
return download_links
#获取下载文件的哈希值
def get_sha256_python(file_path):
sha256_hash = hashlib.sha256()
with open(file_path, "rb") as f:
# 分块读取文件以避免内存问题
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
#读取哈希值
sha256_values = extract_sha256(args.filename)
#读取下载链接
download_links = CMIP6_download_links(args.filename)
# sys.exit(0)
#新建列表用于保存下载成功和下载失败的文件
Success_files = []
wrong_files = []
#下载文件
for index, link in enumerate(download_links, start=1):
#判断目录下是否存在文件
FILE = link.split('/')[-1]
file_path = Path(args.dirout+FILE) # 替换为你的目录和文件名
if file_path.exists():
ACTUAL_HASH = get_sha256_python(args.dirout+FILE)
# print(ACTUAL_HASH)
EXPECTED_HASH = sha256_values[index-1]
# print(EXPECTED_HASH)
if EXPECTED_HASH == ACTUAL_HASH:
print("下载完成:"+FILE)
print("哈希值校验正确")
Success_files.append(FILE)
del ACTUAL_HASH,EXPECTED_HASH
else:
subprocess.Popen("rm -rf "+args.dirout+FILE, shell=True)
print(f"正在下载: {link}")
#使用 mwget 下载
cmd = f"mwget -n "+str(args.n)+" -d "+args.dirout+" "+link
print(cmd)
process = subprocess.Popen(cmd, shell=True)
process.wait() # 等待当前下载完成
#比较文件的哈希值
try:
ACTUAL_HASH = get_sha256_python(args.dirout+FILE)
# print(ACTUAL_HASH)
EXPECTED_HASH = sha256_values[index-1]
# print(EXPECTED_HASH)
if EXPECTED_HASH == ACTUAL_HASH:
print("哈希值校验正确")
Success_files.append(FILE)
del ACTUAL_HASH,EXPECTED_HASH
except:
subprocess.Popen("rm -rf "+args.dirout+FILE, shell=True)
cmd = f"mwget -n "+str(args.n)+" -d "+args.dirout+" "+link
process = subprocess.Popen(cmd, shell=True)
process.wait() # 等待当前下载完成
ACTUAL_HASH = get_sha256_python(FILE)
EXPECTED_HASH = sha256_values[index-1]
# print(EXPECTED_HASH)
if (EXPECTED_HASH == ACTUAL_HASH):
print("哈希值校验正确")
else:
#print("下载错误,请检查")
wrong_files.append(FILE)
del ACTUAL_HASH,EXPECTED_HASH
print("所有文件下载完成!")
print("下载成功的文件:")
print(*Success_files, sep="\n")
print("下载错误的文件:")
print(*wrong_files, sep="\n")
#检查数据是否下载完
#subprocess.Popen("bash "+args.filename+" -s", shell=True)
运行方式:
python *.py 需要下载的.sh文件 下载的线程数(n) 数据的保存路径
2、利用python中的pySmartDL库实现并行下载
pySmartDL 是一个智能的Python下载库,它提供了多线程并行下载功能,可以显著提高文件下载速度。
前提安装pySmartDL库
利用python实现CMIP6数据的并行下载:
#导入库文件
import glob
import os
import argparse
import subprocess
import re
import hashlib
from pathlib import Path
import sys
from pySmartDL import SmartDL
#创建解析器
parser=argparse.ArgumentParser()
parser.add_argument('filename',type=str,help='文件名')
parser.add_argument('n',type=int,help='设置下载的线程数,默认开4个线程')
parser.add_argument('dirout',type=str,help='保存数据的目录')
args=parser.parse_args()
#读取哈希值
def extract_sha256(file_path):
with open(file_path, 'r') as file:
content = file.read()
# 匹配 'SHA256' 后跟任意空白,然后捕获单引号或双引号内的64位哈希
matches = re.findall(r"'SHA256'\s*['\"]([a-fA-F0-9]{64})['\"]", content)
return matches
#读取下载文件的链接
def CMIP6_download_links(file_path):
with open(args.filename,'r',encoding='utf-8') as file:
content = file.read()
#定义正则表达式模式
urls_pattern = r'(https?://[^\s]+?nc\b)'
download_links = re.findall(urls_pattern,content)
return download_links
#获取下载文件的哈希值
def get_sha256_python(file_path):
sha256_hash = hashlib.sha256()
with open(file_path, "rb") as f:
# 分块读取文件以避免内存问题
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
#python并行下载
def smart_download(url, dest=None, threads=args.n):
if dest is None:
dest = os.path.basename(url)
obj = SmartDL(url, dest, threads=threads)
obj.start()
path = obj.get_dest()
#读取哈希值
sha256_values = extract_sha256(args.filename)
#读取下载链接
download_links = CMIP6_download_links(args.filename)
# sys.exit(0)
#新建列表用于保存下载成功和下载失败的文件
Success_files = []
wrong_files = []
#下载文件
for index, link in enumerate(download_links, start=1):
#判断目录下是否存在文件
FILE = link.split('/')[-1]
file_path = Path(args.dirout+FILE) # 替换为你的目录和文件名
if file_path.exists():
ACTUAL_HASH = get_sha256_python(args.dirout+FILE)
# print(ACTUAL_HASH)
EXPECTED_HASH = sha256_values[index-1]
# print(EXPECTED_HASH)
if EXPECTED_HASH == ACTUAL_HASH:
print("下载完成:"+FILE)
print("哈希值校验正确")
Success_files.append(FILE)
del ACTUAL_HASH,EXPECTED_HASH
else:
subprocess.Popen("rm -rf "+args.dirout+FILE, shell=True)
print(f"正在下载: {link}")
#使用python方式并行下载
smart_download(link,args.dirout)
#比较文件的哈希值
try:
ACTUAL_HASH = get_sha256_python(args.dirout+FILE)
# print(ACTUAL_HASH)
EXPECTED_HASH = sha256_values[index-1]
# print(EXPECTED_HASH)
if EXPECTED_HASH == ACTUAL_HASH:
print("哈希值校验正确")
Success_files.append(FILE)
del ACTUAL_HASH,EXPECTED_HASH
except:
subprocess.Popen("rm -rf "+args.dirout+FILE, shell=True)
smart_download(link,args.dirout)
ACTUAL_HASH = get_sha256_python(FILE)
EXPECTED_HASH = sha256_values[index-1]
# print(EXPECTED_HASH)
if (EXPECTED_HASH == ACTUAL_HASH):
print("哈希值校验正确")
else:
#print("下载错误,请检查")
wrong_files.append(FILE)
del ACTUAL_HASH,EXPECTED_HASH
print("所有文件下载完成!")
print("下载成功的文件:")
print(*Success_files, sep="\n")
print("下载错误的文件:")
print(*wrong_files, sep="\n")
#检查数据是否下载完
#subprocess.Popen("bash "+args.filename+" -s", shell=True)
运行方式:
python *.py 需要下载的.sh文件 下载的线程数(n) 数据的保存路径
3、结果比较
并行下载的速度:

😉
个人记录,仅供参考哦~

评论区
评论加载中...