
简介面向气象科研人员、数据爱好者及Python技能进阶者这份资料系统演示了如何借助Python批量获取ECMWF欧洲中期天气预报中心数据涵盖API密钥配置、请求参数构造、JSON响应解析、文件保存、异常处理及多线程下载等关键环节适合定时抓取大量气象产品的应用场景。资源共含5个文件压缩包约29.53MBpy脚本为可直接运行的下载程序doc图文教程分步骤讲解环境准备到调试运行的完整流程rar与exe分别提供ECMWF API客户端和Python 3.6安装包txt文件可做参数记录与说明搭配使用即可快速上手。已有5672人学习关注度较高。通过这份材料读者既能直接调用脚本完成批量获取也能深入理解请求库、进度显示、存储管理等编码细节进而按自身需求灵活扩展下载方案。1. 项目背景与整体思路1.1 为什么需要批量下载ECMWF数据做气象、气候、水文或者环境方向研究的人对ECMWF欧洲中期天气预报中心这套数据体系一定不陌生。ERA5再分析资料、ERA5-Land高分辨率陆面数据、季节预报数据这些几乎是科研场景里的硬通货。但真到下载环节很多人的第一反应还是打开网页选好变量、时间、区域然后点提交等它生成链接再手动下载。这个流程在数据量小的时候还凑合一旦涉及长序列、多变量、多区域比如要下载1990年到2020年逐小时的降水、风速、温度手动操作就能把人搞崩溃。且不说网页端频繁切换很麻烦ECMWF后台的请求队列有时候要排队几个小时一个请求失败就得重来根本没有效率可言。所以用Python脚本批量提交请求、统一管理下载任务就成了处理这类数据需求的基本功。我最早接触ECMWF数据下载是好几年前当时要下整整十年的ERA5逐小时数据十几个变量分区下载一开始手动操作到第三天就彻底放弃了。后来老老实实花了一个下午把Python下载脚本跑通从那以后遇到新数据集需求基本都是先写脚本再干活。这也是我把这个项目整理成一篇实操记录的原因——我踩过的坑大家可以少踩一遍。1.2 整体技术方案选型ECMWF提供了官方的数据服务接口CDSClimate Data Store用户通过注册账号获取API密钥然后借助Python的cdsapi库提交数据请求并下载结果。这套机制本质上是请求-处理-下载的异步任务模式你提交一个数据请求ECMWF服务器把它加入队列处理完之后给你一个下载链接你再通过脚本拉取数据。既然要批量下载方案的核心就是两件事如何高效地循环提交多个请求以及如何在请求失败、网络中断的情况下保证任务能完整跑完。我的技术选型就是这么定的Python cdsapi库负责请求提交和数据下载脚本采用按时间分段循环的策略并加入请求状态检测和自动重试逻辑。整个过程不需要额外的存储服务也不需要数据库一台普通电脑挂着就行属于典型的小成本高收益方案。另外说句实话市面上也有人用wget、curl直接在链接后面拼参数下载理论上可行但遇到需要按天循环、按变量切换的场景代码复杂度反而上去了。Python的优势在于生态成熟、cdsapi库官方维护、报错信息相对友好对非专业开发人员来说是最容易上手的选择。2. 环境准备与账号配置2.1 Python环境安装这一步是所有人的第一道门槛。现在ECMWF的CDS API要求Python 3.6以上版本我建议直接装3.8以上的毕竟新版本库的兼容性更好。如果你之前没装过Python去python官网下载安装包安装的时候记得勾选Add Python to PATH这一步很多新手会漏掉漏掉之后在命令行里输入python会提示找不到命令后面所有操作都进行不下去。装好之后在命令行里验证一下python --version能正常输出版本号说明安装成功。如果提示没有这个命令大概率就是PATH的问题重新安装并勾选添加环境变量即可。这里再补充一句macOS和Linux用户一般系统自带Python但版本可能偏老建议直接用pyenv或者系统包管理器装一个新版本。2.2 注册ECMWF账号并获取API密钥在开始写代码前必须先去CDS官网注册账号并拿到专属的API密钥。这个密钥是连接你本地环境和ECMWF服务器的凭证相当于一把钥匙。具体流程是在CDS网站注册登录后进入个人主页找到API key一栏里面会显示你的UID和一串密钥。这两个字符串在后面的配置文件中会用到一定要复制保存好。注意这个密钥是和个人账号绑定的不要泄露给他人否则别人可以用你的账号额度去下载数据。注册过程中有一个容易忽略的细节很多数据集的访问需要单独同意使用协议。比如首次下载ERA5数据时CDS会要求你在数据集页面勾选并同意许可协议否则即使API密钥配置正确提交请求后也会报错提示你还没有授权访问这个数据集。所以拿到密钥之后建议先到目标数据集页面点一下Download data按钮走一遍网页端请求流程确认自己有权访问再回到脚本里干活。2.3 cdspai库的安装与密钥配置文件环境装好后接下来安装Python数据下载的核心库cdsapi。这个库是ECMWF官方维护的Python客户端封装了与CDS服务器交互的所有细节。安装非常简单pip install cdsapi如果你的环境里同时有Python 2和Python 3可能需要用pip3来安装。然后需要配置密钥文件。Windows系统下在用户目录下创建一个名为.cdsapirc的文件Linux和macOS同理文件名也是.cdsapirc。文件内容格式如下url: https://cds.climate.copernicus.eu/api key: 你的UID:你的API密钥注意key的格式是UID和密钥之间用英文冒号分隔中间没有空格。配置完成后可以运行一段极简单的测试代码验证配置是否生效import cdsapi c cdsapi.Client() print(配置成功)如果打印出配置成功说明客户端实例化正常可以进入下一步了。如果这里报错绝大多数情况是配置文件路径不对或者key格式写错了优先检查这两处。3. 核心代码实现与参数详解3.1 单次数据请求脚本拆解拿到一个ECMWF数据集首先要学会看它的请求结构。以最常用的ERA5数据为例一个标准的CDS请求由数据集名称、请求参数和目标文件名三部分组成。下面是一段完整的单次下载脚本import cdsapi c cdsapi.Client() c.retrieve( reanalysis-era5-single-levels, { product_type: reanalysis, variable: [2m_temperature, total_precipitation], year: 2020, month: 06, day: [01, 02, 03], time: [00:00, 06:00, 12:00, 18:00], data_format: netcdf, area: [50, 110, 20, 135], }, era5_sample.nc )参数含义逐一说清楚product_type指定数据产品类型ERA5的再分析数据填reanalysisvariable指定要下载的变量这里我选了2米气温和总降水变量名必须在CDS数据集页面提供的列表中找拼错一个字母就会报错year、month、day、time控制时间范围注意这几个字段不一定接受列表有些数据集只支持单个值需要先查清楚data_format是输出格式ERA5支持netcdf和grib两种我一般用netcdf因为后续用xarray处理更方便area定义下载区域格式是北纬、西经、南纬、东经四个值我这里设置的是中国中东部区域。这里特别提醒一个绝大多数人都会踩的坑ECMWF的经纬度顺序是[北, 西, 南, 东]不是常见的[左上, 右下]更不是[经度, 纬度]。我第一次用这套接口时按照grib格式的习惯写反向区域下载下来的数据范围完全不对检查了大半天才意识到是顺序问题。3.2 循环批量下载的完整实现单次请求跑通之后批量下载就只是把单次请求包装到循环里的问题。核心思路是按时间切片逐期提交请求每次请求的数据量控制在合理范围内避免一次提交超大数据集导致服务端排队过长甚至请求失败。以按年循环为例import cdsapi c cdsapi.Client() years [1990, 1991, 1992, 1993, 1994] months [01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12] variables [2m_temperature, total_precipitation] for year in years: for month in months: print(f正在提交 {year}-{month} 的请求...) c.retrieve( reanalysis-era5-single-levels, { product_type: reanalysis, variable: variables, year: year, month: month, day: [f{d:02d} for d in range(1, 32)], time: [00:00, 06:00, 12:00, 18:00], data_format: netcdf, area: [50, 110, 20, 135], }, fera5_{year}_{month}.nc ) print(f{year}-{month} 提交完成)运行这段脚本它会逐月提交请求。这里有一个关键技巧day参数用列表生成式[f{d:02d} for d in range(1, 32)]可以自动生成01到31的日期列表不需要手写一大串数字。等脚本把请求全部提交完服务器端会依次处理每个请求生成的文件会按era5_1990_01.nc、era5_1990_02.nc的格式保存到本地。实际的下载逻辑也在这个循环里c.retrieve会等待服务端处理完当前请求并完成下载才会进入下一次循环。所以脚本只要不中断就会一直运行到所有文件下载完成。不过这个过程中有几个需要特别注意的点我在下一节统一讲。3.3 请求参数中的高频问题和避坑心得先说变量名的问题。很多新手喜欢按照文献或者别人的代码里写的变量名直接用然后发现报错。ECMWF不同数据集允许请求的变量名是有差异的比如2m_temperature在ERA5里是正确的但换成ERA5-Land数据集后变量名可能变成了2m_temperature加上特定的product_type组合。最稳妥的办法是到CDS数据集页面点开Download data标签页那里有图形化的变量选择界面下拉框里的选项就是脚本里能用的合法变量名。再说时间字段。有些数据集对time字段只接受固定的几个时次比如ERA5是00:00到23:00每小时一个但某些衍生产品只有3小时间隔或者6小时间隔填了不存在的时次会报Bad request for url之类的错误。处理方式是先做一次小范围测试请求比如只下一天的某个时次确认无误后再铺开跑全量。最后说目标文件名。c.retrieve的第三个参数是本地的保存文件名完全可以按需求自由命名但建议遵循数据集_时间_区域的结构化命名方式方便后续管理。如果下载中断了或者想补某个时间段的数据清晰的命名能让你少很多麻烦。4. 实操过程中的常见问题与排查技巧4.1 请求长时间排队卡住不动这是使用ECMWF数据下载时遇到最多的状况。明明提交了一个请求服务器也不报错但就是一直转圈。原因在于CDS采用异步处理队列当某个时间段请求量很大时你的任务可能排在几千个任务之后等待时间难以估计。我的处理办法是不在循环里干等而是把大批量任务拆成多个小任务分批次提交。比如连续提交10个请求每个请求只包含一个月的6个变量不要一次性提交10年所有变量。这样做的好处是单个任务处理时间短、失败率低即使中途断了重跑的代价也可控。另一个实用技巧是给脚本加上运行时长限制。对于单个请求如果超过一定时间比如30分钟还没下载完成就跳过进入下一个请求最后统一补漏。这个可以通过在请求前记录时间戳、请求后检查文件是否生成来实现代码逻辑很简单但能显著提升大批量任务的可靠性。4.2 服务器返回HTTP错误代码的处理跑批量下载时经常会遇到HTTP 400、HTTP 429等错误。它们的意思完全不同HTTP 400请求参数有误通常是变量名、时间格式、区域范围不合法。排查方法很简单把请求参数和CDS网页端的图形化选择界面做比对重点检查变量名和区域顺序。HTTP 429请求频率过高触发了限流策略。这时候最忌讳的是脚本继续快速重试反而会加重限流。正确做法是等待一段时间比如60秒再继续。HTTP 500服务端暂时性错误属于ECMWF那边的问题过几分钟重试通常能解决。针对这些情况我一般会在代码里加上异常捕获和退避重试逻辑import time import cdsapi c cdsapi.Client() def download_with_retry(c, params, filename, max_retries5): for attempt in range(max_retries): try: c.retrieve(params[dataset], params[request], filename) return True except Exception as e: wait_time 2 ** attempt * 30 print(f请求失败: {e}, {wait_time}秒后重试...) time.sleep(wait_time) return False这里用指数退避策略第一次失败等30秒第二次等60秒依次翻倍避免频繁请求把服务器惹毛。4.3 磁盘空间不足与增量下载策略ERA5逐小时、多变量的nc文件体积不小动辄几百MB如果下载整个中国区域几十年的数据总存储需求会非常夸张。很多人的电脑硬盘根本装不下。这也是为什么我强烈建议在批量下载前先估算数据量而不是无脑全量下载。我个人的习惯是先用网页端下一个最小测试文件比如某一天的一个变量查看文件大小然后乘以天数、乘以变量数估算总需求。如果超出了可用磁盘空间就要调整策略要么减少区域范围要么只下载需要的变量要么压缩时间频率。在这个基础上还可以做增量下载。比如脚本已经下载了1990年到2020年的数据新需求只需要2020年以后的数据那就调整年份列表只提交2020年之后的请求。这个场景非常常见所以我在脚本里专门设计了可以灵活修改的年份、月份、变量列表参数换需求时只改列表内容就行不会影响其他逻辑。4.4 文件名与断点续传的安全检查还有一个容易被忽略但极其重要的问题同一个文件名如果已存在retrieve会怎么处理不同版本行为可能不一样有的版本会直接覆盖有的版本会报错。为了稳妥起见我会在下载前检查目标文件是否已存在且大小不为0如果条件满足就跳过当前请求。import os filename fera5_{year}_{month}.nc if os.path.exists(filename) and os.path.getsize(filename) 0: print(f{filename} 已存在跳过) continue这个小技巧特别适合大批量任务中断后的补跑。跑了一上午任务中途由于网络原因断了不用全盘重来只需要重新运行脚本它会把已经下载好的文件自动跳过去只补缺失的文件。5. 完整工程化脚本示例与扩展思路5.1 整合后的批量下载脚本把前面各节的关键逻辑整合成一份完整的工程化脚本结构包括参数配置区、循环主体、异常处理、已完成文件跳过。代码结构如下import os import time import cdsapi # 配置区 DATASET reanalysis-era5-single-levels VARIABLES [2m_temperature, total_precipitation] YEARS [1990, 1991, 1992] MONTHS [f{m:02d} for m in range(1, 13)] DAYS [f{d:02d} for d in range(1, 32)] TIMES [00:00, 06:00, 12:00, 18:00] AREA [50, 110, 20, 135] OUTPUT_FORMAT netcdf c cdsapi.Client() def already_downloaded(filename): return os.path.exists(filename) and os.path.getsize(filename) 0 def download_file(year, month): filename fera5_{year}_{month}.nc if already_downloaded(filename): print(f{filename} 已存在跳过) return request { product_type: reanalysis, variable: VARIABLES, year: year, month: month, day: DAYS, time: TIMES, data_format: OUTPUT_FORMAT, area: AREA, } for attempt in range(5): try: print(f提交 {year}-{month} 请求...) c.retrieve(DATASET, request, filename) print(f{filename} 下载完成) return except Exception as e: wait 30 * (2 ** attempt) print(f请求异常: {e}, {wait}秒后重试) time.sleep(wait) if __name__ __main__: for year in YEARS: for month in MONTHS: download_file(year, month) print(全部任务处理完毕)这段脚本可以原样复制保存为era5_download.py然后直接运行python era5_download.py运行时留意控制台输出如果看到某个年份月份提示已存在跳过说明断点续传在正常工作。整个脚本不需要额外依赖逻辑也不复杂适合直接作为项目模板复用。5.2 多变量多区域的批量组合策略实际项目中往往需要下载的不止一个区域、一组变量。比如气候分析中常见的是把中国分几个大区分别处理或者需要同时下载多个高度的风场数据。这时候我的做法是再套一层区域和变量组的循环外层遍历区域配置内层遍历变量组合文件名里把区域标识也带进去。这里需要注意的是ECMWF服务器对单位时间内提交的请求数量有限制如果循环提交太快很容易触发限流。所以多组合循环时要控制节奏每提交8到10个请求后主动停顿几秒具体间隔可以在实际运行中调整以不触发429错误为准。5.3 从nc文件到分析结果的后续处理建议数据下载完成不代表工作结束。拿到nc文件后通常用xarray配合pandas进行后续处理。比如提取某个网格点的时序数据、计算区域平均值、把逐小时数据重采样成逐日数据这些操作用xarray都是一行代码的事。import xarray as xr ds xr.open_dataset(era5_1990_01.nc) temp ds[t2m] - 273.15 daily_mean temp.resample(time1D).mean()这里做了一次开尔文到摄氏度的转换然后重采样成日均温。xarray的resample接口和pandas几乎一样熟悉pandas的人上手很快。这种Python批量下载 xarray分析的组合基本覆盖了从数据获取到初步分析的全过程也是我目前在项目里最常使用的工作流。写在最后跑ECMWF批量下载这个项目给我最大的感受就是官方文档写得再清楚也不如自己动手跑一遍踩坑学得快。密码学配置、变量名合法性、区域顺序、队列等待、断点续传每一个环节都有看似不起眼但实际操作时会卡住的地方。希望这篇记录能帮你减少一些不必要的试错时间。最后再分享一个小技巧第一次跑大批量任务前一定要先用一个小范围请求做走通测试比如只下一天的2个变量确认文件名、数据内容和预期一致后再放开了跑全量。这一步看着多花了十分钟实际上可能帮你省下的是好几个小时的无效等待和排查时间。本文还有配套的精品资源点击获取