当前位置:首页>python>Python+IDM批量下载ERA5数据

Python+IDM批量下载ERA5数据

  • 2026-10-05 12:50:08
Python+IDM批量下载ERA5数据
ERA5数据位于Climate Data Store(CDS)网站上,网址:

https://cds.climate.copernicus.eu/#!/home


1  注册或登录CDS平台

CDS平台指的是哥白尼气候变化服务(Copernicus Climate Change Service, C3S)的Climate Data Store (CDS)。这是一个获取全球气候数据(包括ERA5再分析数据)的权威官方平台。

2 登录后进入User guide

  • 点击上方User guide
  • 点击API service

  • 在这个Setup the CDS Api key下面找到你的url和key,后面配置时需要。


3 配置API

  • 在“C:\Users\用户名” 下创建一个“.cdsapirc” 文件,创建方法:

  • 先创建一个 “.cdsapirc.txt” 文件,输入下方格式的url和key信息,然后再把 “.txt” 删掉。

url: https://cds.climate.copernicus.eu/api

key: your key

  • ctrl+R打开cmd,安装cdsapi第三方库,输入:pip install cdsapi


4 下载安装IDM软件

IDM下载官网:https://www.internetdownloadmanager.com

支持付费下载正版,或于CSDN/B站等平台获取安装包。

要记住IDMan.exe的安装路径,后续代码批量下载时需要。


5 批量下载Python脚本

支持多线程,同时加载多个ERA5数据。

如果下载失败,注意检查API配置文件输入的url和key是否正确。

import cdsapiimport osfrom subprocess import callfrom concurrent.futures import ThreadPoolExecutor  # 添加线程池支持def idmDownloader(task_url, folder_path, file_name):    """    IDM下载器:param task_url: 下载任务地址:param folder_path: 存放文件夹:param file_name: 文件名:return:    """# IDM安装目录idm_engine = "D:/IDM/Internet Download Manager/IDMan.exe"# 将任务添加至队列call([idm_engine, '/d', task_url, '/p', folder_path, '/f', file_name, '/a'])# 开始任务队列call([idm_engine, '/s'])# ConfigurationyearStart = 2000yearEnd = 2025grid = 0.25  # 0.25 degree resolution# variable = 'q'  # specific humidity# variable = 'sp'  # surface pressure# variable = 'e'  # evaporation# variable = 'tp'  # total precipitation# variable = 'hgt'# variable = 'uwnd'# variable = 'vwnd'# variable = 'wwnd'# variable = 'air'# variable = 'slp'# variable = 'air2m'variable = 'u10m'base_path = r'\data\ERA5'path = os.path.join(base_path, variable)  # 存放文件夹# Create output directory if it doesn't existos.makedirs(path, exist_ok=True)# Prepare year and month listsyears = range(yearStart, yearEnd + 1)yr = [str(i) for i in years]months = range(1, 13)mo = [str(j).zfill(2) for j in months]# Pressure levels to downloadpressure_levels = ["1", "3", "5", "7", "10", "30", "50", "70", "100","150", "200", "250", "300", "400", "500", "600","700", "850", "925", "975", "1000"]times = ["00:00", "01:00", "02:00","03:00", "04:00", "05:00","06:00", "07:00", "08:00","09:00", "10:00", "11:00","12:00", "13:00", "14:00","15:00", "16:00", "17:00","18:00", "19:00", "20:00","21:00", "22:00", "23:00"]def download_month(iyr, imo):""" 下载单个月份数据的函数 """year_path = os.path.join(path, str(yr[iyr]))    os.makedirs(year_path, exist_ok=True)    filename = variable + f'.6h.global.{grid}deg.{yr[iyr]}.{mo[imo]}.nc'#filename = variable + f'.1h.global.{grid}deg.{yr[iyr]}.{mo[imo]}.nc'output_file_path = os.path.join(year_path, filename)if os.path.exists(output_file_path):print(f'File {output_file_path} already exists. Skipping download.')returnprint(f'======= Downloading: {variable} | date: ' + yr[iyr] + '.' + mo[imo] + ' =======')try:        c = cdsapi.Client()  # 每个线程创建独立的客户端r = c.retrieve('reanalysis-era5-single-levels',# "reanalysis-era5-pressure-levels",{'product_type': 'reanalysis',# "variable": ["geopotential"],                # "variable": ["specific_humidity"],                # "variable": ["evaporation"],                # "variable": ["total_precipitation"],                # "variable": ["surface_pressure"],                # "variable": ["u_component_of_wind"],                # "variable": ["v_component_of_wind"],                # "variable": ["temperature"],                # "variable": ["vertical_velocity"],                # "variable": ["2m_temperature"],                #"variable": ["mean_sea_level_pressure"],"variable": ["10m_u_component_of_wind"],'year': yr[iyr],'month': mo[imo],'day': ['01', '02', '03', '04', '05', '06','07', '08', '09', '10', '11', '12','13', '14', '15', '16', '17', '18','19', '20', '21', '22', '23', '24','25', '26', '27', '28', '29', '30','31'],"time": ["00:00", "06:00", "12:00", "18:00"],#"time": times,                # "pressure_level": pressure_levels,'format': 'netcdf',"download_format": "unarchived",'grid': [grid, grid],  # 0.25° resolution})        url = r.location  # 获取文件下载地址idmDownloader(url, year_path, filename)  # 添加进IDM中下载except Exception as e:print(f"Error downloading {variable} for {yr[iyr]}-{mo[imo]}: {str(e)}")# 将错误信息写入日志文件with open(os.path.join(path, "download_errors.log"), 'a') as f:            f.write(f"{variable}_{yr[iyr]}-{mo[imo]}: {str(e)}\n")return# 创建线程池控制并发数max_workers = 2  # 设置最大并发线程数tasks = [(i, j) for i in range(len(yr)) for j in range(len(mo))]  # 生成所有任务参数with ThreadPoolExecutor(max_workers=max_workers) as executor:# 使用lambda解包参数元组executor.map(lambda params: download_month(*params), tasks)print("所有下载任务已添加到IDM队列!请检查IDM开始下载。")

最新文章

随机文章