
我刚入行做气候数据分析那阵子拿到导师的第一个任务就是“把研究区的ERA5数据下载下来”。那时候被各种名词绕得晕头转向CDS是什么、MARS是什么、为什么有人说网页下载有人说API、NetCDF和GRIB到底选哪个。折腾了一整天最后总算把数据弄到手也把下载这件事的完整链路跑通了。后来这几年我几乎每个月都要下一批ERA5数据网页端和API脚本两种方式都经常用踩过的坑也够写一篇长文了。这篇就把ERA5下载的两种主流方式完整拆开讲清楚一种是面向零基础、单次少量取数的网页图形界面下载另一种是适合批量、自动化、重复取数的CDS API脚本下载。文中会把注册配置、表单字段含义、脚本写法、常见报错、格式选择这些细节全部补齐就算你完全没接触过再分析数据照着走也能顺利拿到第一份ERA5数据。如果你已经在用ERA5但总被下载环节卡住那这篇更值得看完很多坑是没有实际操作过的人根本写不出来的。1. 先把ERA5是什么讲清楚再谈下载1.1 一张再分析数据表到底有什么ERA5是ECMWF欧洲中期天气预报中心发布的第五代全球再分析资料。所谓再分析简单理解就是把过去几十年里能收集到的所有观测资料气象站、探空、卫星、浮标、飞机报等统统喂进一个固定的数值天气预报模型里做一遍统一、一致的“历史回放”产出一套时空连续、物理自洽的格点数据。这套数据好用在哪儿第一它覆盖的时间长从1940年到现在基本不断档第二它是全球网格化数据空间分辨率到0.25°×0.25°相当于水平格距大约31公里时间分辨率逐小时第三变量非常全地表层的2米气温、10米风、降水、海平面气压、土壤温湿度以及从1000hPa到1hPa共37层气压层上的温度、位势高度、相对湿度、风场、比湿、臭氧等等都有。正因为ERA5覆盖面广、时间连续、又完全免费开放它几乎成了当前地学、气象、水文、农业、生态、能源这些领域里最常用的“背景数据源”。写论文需要一段长时间序列的气温变化缺测站点的气象要素插补或者给水文模型做大气驱动很多人第一反应就是“去下载ERA5”。下载这件事本身不难难点在于第一次接触的人往往不知道去哪下、怎么选参数、下完怎么打开。下面我先把两种下载方式的底层逻辑说清楚。1.2 两种下载方式的选择逻辑ERA5数据存放在ECMWF的气候数据商店CDSClimate Data Store上。用户在CDS网站提交“数据请求”ECMWF后台把你需要的那一块数据从庞大的归档库里提取、裁剪、重采样加工成你选的格式再通过网页或API把文件交给你。这就决定了有两种完全不同的驱动方式网页图形界面下载你打开浏览器在CDS网站上一项一项填表选变量、选时间、选区域点提交然后在后台任务列表里等着等任务完成再点链接下载。这种方式的优点是直观、门槛低不需要写一行代码缺点是如果涉及几十个年份、几百个文件重复操作会把人逼疯。CDS API脚本下载ECMWF提供了一套HTTP API接口你用Python的cdsapi库写脚本把你的需求写成参数Python自动提交请求、等待、下载。这种方式适合批量获取长序列数据能自动化、能断点续传、能嵌入到数据处理pipeline里。一句话总结偶尔下一次、数据量不大、不打算写代码用网页批量下载、长序列、要重复运行、要集成到自己的处理流程里用API。我自己的习惯是第一次接触某个新产品或新变量时先在网页端点一遍确认参数没问题然后把这个参数原封不动转成API脚本以后就全自动了。2. 下载前必须完成的准备一项都不能省2.1 注册账号并拿到API Key无论用网页还是API第一步都是注册一个CDS账号。直接在CDS官网右上角点注册用邮箱收验证邮件激活就行。这里有个细节注册完成后你先去网页上把CDS的使用条款接受一下很多人的API请求老是返回403检查到最后就是没接受许可协议。如果只是网页下载注册到这里就够了。但如果想用API方式还需要单独拿API Key。登录后进入个人账户页面找到API Key那一栏你会看到类似下面这样的信息URL: https://cds.climate.copernicus.eu/api Key: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx这个Key是私有的相当于你身份凭证的一部分不要贴到公开仓库里。后面配置Python环境时会用到。2.2 把需求拆成CDS表单字段很多人卡在下载第一步不是不会点鼠标而是不知道表单里的每一项该填什么。不管网页还是API你的需求最终都会被翻译成下面这几个固定字段我把它们逐个解释清楚字段含义举例Product type产品类型通常选reanalysis即正式的ERA5再分析reanalysisVariable变量决定要哪一类物理量2m_temperature、total_precipitationYear / Month / Day时间范围网页上可以多选2020年01到12月Time一天内的哪些时次ERA5是逐小时数据00:00到23:00步长1小时Geographical area地理区域限制经纬度范围[60, -10, 40, 30]Format文件格式netcdf或grib有几点特别容易踩坑必须先说Geographical area的填法是北、西、南、东不是很多人以为的“西、东、南、北”。比如要中国区域可以填[53, 73, 18, 135]也就是北纬53°、西经东经73°、南纬18°、东经135°。这里的“西”如果跨过0°经线用负值表示例如欧洲区域可以写[60, -10, 40, 30]。Year、Month、Day、Time在网页上都能多选但是注意多选和单个选择最终生成的数据体量可能差距巨大。你选了10个年份、12个月、31天、24个时次这个请求的大小可能是单次请求的几千倍。Format的选择很关键普通分析画图建议直接选netcdf后面处理最省事如果要做数值模式驱动或者要用传统气象软件读可能要考虑grib。第5部分我会专门展开讲这两者的区别。2.3 量化你的数据量区域、时间步长和变量数下载ERA5之前我强烈建议你先估算一下自己到底需要多少数据。很多新手一上来就选“全球范围、1940年至今、逐小时、所有变量”然后请求提交几分钟后直接被系统拒了或者挂在队列里几天都下不来。ERA5的空间分辨率是0.25°全球格点数大约是1440×721超过一百万个格点。一个单层变量在全球范围、逐小时、存成NetCDF一年的数据量就可能到几十GB量级。如果你还要多层气压层、多个变量数据量还会线性翻倍。所以合理的做法是在满足研究需求的前提下尽量把数据范围缩小区域能选中国、欧洲、某个省就尽量不要全选全球时间步长能要6小时的就不要24个时次全选变量只选自己真正要算的那几个别顺手全勾上如果只是为了看季节平均可以先用ERA5的月平均产品而不是下载逐小时数据后自己再算。我见过太多人在这一步翻车请求巨大、等待半天、最后下载一个几十GB的文件本机内存和磁盘都扛不住。先小范围试跑一次确认数据质量和处理流程没问题再扩大范围是效率最高的路径。3. 方式一网页图形界面下载适合零基础和单次取数3.1 一步步完成表单提交网页下载的第一步是进入CDS数据集页面。在CDS主页的搜索框里输入ERA5找到ERA5 hourly data on single levels from 1940 to present这个数据集。注意还有一个ERA5 hourly data on pressure levels from 1940 to present区别在于前者是地表单层变量后者是多层气压层变量——下载气压层的温度、风、位势高度时要去后者。进入数据集页面后点击Download data标签页你会看到一个长长的表单。以“下载2020年1月中国区域的地表2米气温每天4个时次”为例填写逻辑是Product type选Reanalysis。对绝大多数使用场景选这个就够了。Variable搜索并勾选2m temperature。Year选2020。Month选01。Day把01到31全部勾上或者用页面上的全选按钮。Time这里建议别勾24个。比如只想看日变化可以勾00:00、06:00、12:00、18:00。Geographical area勾选“North: 53, West: 73, South: 18, East: 135”。Format选NetCDF。全部填完后页面右侧会实时显示“Number of requests: 1”和数据量预估。确认没问题点击Submit form任务就进了CDS后台队列。这里有个小技巧网页表单底部通常有个Show API request按钮点击后它会直接生成一段和你的填写完全对应的Python代码。即使你这次用网页下载也建议把这个代码复制保存下来以后要批量下载时直接改年份就能用不用再重新填表。3.2 队列等待与下载提交请求后进入Your requests或My requests页面能看到任务状态。ERA5的请求一般会经历这几个状态Queued → Running → Completed → Download刚提交时是Queued表示排进了处理队列Running表示ECMWF正在你的数据切片处理完成后变成Completed旁边会出现下载按钮。等待时间取决于数据量和当前服务器的繁忙程度。小数据量可能几十分钟就好大数据量等上几小时甚至一两天都不奇怪。这里给个经验值供参考中国区域、单变量、一年、逐6小时数据通常半小时到一小时左右能完成全球、单变量、一年、逐小时可能要等好几个小时。任务完成后下载链接会保留一段时间不同时期政策不同但通常不是永久的建议下载到本地磁盘后第一时间检查文件完整性最好解压后用xarray或ncdump打开看一眼确认不是损坏文件。不要拖到过期再想起来下。3.3 网页方式最容易卡住的地方我见过很多人在网页端反复提交却怎么也成功不了问题往往出在下面几个点上没有接受许可协议新注册账号第一次使用时需要先在产品页面上接受数据许可。否则提交请求时可能直接报错或者任务反复失败。请求数据量超出限制ECMWF对单个请求的数据规模有上限如果你选的年份太多、变量太多、范围太大提交后会自动失败或一直在队列里不动。解决办法是拆小请求比如按年拆、按变量拆。弹窗或页面超时CDS网页端偶尔会在提交大请求时页面会话过期看起来像是“没反应”。这时候不要重复点提交先去请求列表里确认这个请求到底有没有进去。我遇到过连续点三次提交、结果后台排了三个一模一样的任务白白占用下载额度。下载链接点击无响应有些浏览器会拦截CDS的下载跳转或者文件名带特殊字符导致下载失败。换一个主流浏览器试试或者右键复制下载链接用下载工具。注意下载工具如果开太多线程可能被服务器限流。网页端本身就是给“偶尔用一次”的场景设计的它的优点是所见即所得、能直接看到请求参数和预估数据量缺点也很明显——如果你要下载1990到2020年逐年逐月的几百份数据靠鼠标点不太现实。这也是为什么我在实际工作中90%的情况都走API网页端只用来做参数试探和Debug。4. 方式二CDS API脚本下载批量自动化才是研究常态4.1 安装与配置API方式的核心是cdsapi这个Python库。安装很简单pip install cdsapi装完之后需要在你的用户目录下创建一个配置文件.cdsapircWindows系统路径是C:\Users\你的用户名\.cdsapircLinux/macOS是~/.cdsapirc。文件内容url: https://cds.climate.copernicus.eu/api key: 你自己的UID:APIKey注意新版账号的API Key通常是一串UUID但部分老教程里写的是UID:UUID格式。如果你配置后请求报401认证错误检查一下是不是把这截字符串的格式写错了。建议直接复制CDS个人页面上给出的那一段完整字符串包括冒号。配置完成后在Python里运行一句import cdsapi c cdsapi.Client()如果没有报错说明认证已经通过。接下来就能写真正的下载脚本了。4.2 一个能直接用的下载脚本下面是下载“2020年1月中国区域2米气温、4个时次”的完整脚本我加了详细注释import cdsapi c cdsapi.Client() c.retrieve( reanalysis-era5-single-levels, { product_type: reanalysis, variable: 2m_temperature, year: 2020, month: 01, 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], area: [53, 73, 18, 135], format: netcdf, }, era5_t2m_202001.nc, )脚本运行后终端会输出请求提交信息然后进入等待轮询。cdsapi库会每隔一段时间请求一次CDS服务器询问任务是否完成。任务完成后数据文件会自动下载到你指定的路径。这个脚本的核心就是retrieve()这个函数第一个参数是数据集名称第二个是请求参数的字典第三个是保存的文件名。如果跑通了后面所有下载都是往这个模板里填参数。4.3 批量多年份与断点续下真正体现API价值的场景是批量下载。比如我要1950到2020年每年1月的2米气温不可能在网页上手动跑71次用Python循环即可import cdsapi import os c cdsapi.Client() for year in range(1950, 2021): outfile fera5_t2m_{year}01.nc if os.path.exists(outfile): print(f{outfile} 已存在跳过) continue c.retrieve( reanalysis-era5-single-levels, { product_type: reanalysis, variable: 2m_temperature, year: str(year), month: 01, day: [f{d:02d} for d in range(1, 32)], time: [00:00, 06:00, 12:00, 18:00], area: [53, 73, 18, 135], format: netcdf, }, outfile, )这里有两个非常实用的经验断点续传逻辑循环开始前先判断目标文件是否已经存在存在就跳过。ERA5下载量一大网络中断、服务器超时太常见了加上这行判断中断后重新运行脚本就能接着没下完的年份继续不用从头再来。任务拆分的粒度我是按“年”拆请求而不是把71年塞进一个请求。因为单个请求数据量太大会被限制而且一旦失败重来成本很高。按年拆分还有一个好处可以细粒度地观察每个年份是否下载成功。如果你觉得一个个月下太碎也可以把整年12个月放进同一个请求这样一年一个文件变通方法year: str(year), month: [f{m:02d} for m in range(1, 13)],这样一年一个文件管理起来更方便。但要注意最终文件大小如果一年都超过了几GB甚至十几GB打开和处理都会卡建议还是按需分月。4.4 配合网页端“Show API request”快速生成参数写API脚本最大的障碍不是Python语法而是请求参数的字段名记不住。比如你只记得“相对湿度”不知道它在CDS里叫relative_humidity“海平面气压”叫mean_sea_level_pressure硬背很容易出错。我的办法是先在网页端把表单填一遍然后点开Show API request把生成的Python代码直接复制过来改。这样既保证了参数名称绝对正确又避免了漏字段。这个技巧墙裂推荐给所有第一次用API的人。另外一个办法是直接在数据集详情页找Download data标签下的“Available variables”列表里面所有变量名都列清楚了检索的时候复制粘贴即可。再不行就用网页端提交一次等它Completed之后在请求详情页同样能看到它对应的API请求代码。总之网页端是API脚本的参数调试器两者不是互斥关系而是互补关系。5. 数据到手之后格式兼容、变量对照与常见坑5.1 NetCDF还是GRIB下载前就要想清楚这个问题最好在提交请求前就决定因为下载格式直接决定了后面所有处理工具链。NetCDF是目前地学领域最常见的科学数据格式之一Python的xarray可以直接打开变量名、维度、属性一目了然。对绝大多数做统计分析、画图、做深度学习的人来说选NetCDF最省心。CDS上标注NetCDF是“experimental”但实际使用下来非常稳定至少我这几年的数据没遇到过打不开的情况。GRIB是气象领域的原生二进制格式WMO世界气象组织标准存储压缩率更高很多传统气象软件如WRF前处理、Metview直接原生支持。但它不是自描述的普通工具打开需要额外安装cfgrib引擎。如果你下载的是气压层数据后续要做剖面图、做WRF模式的初始场输入GRIB更合适。如果只是想算一个区域平均气温、画一张降水分布图那没必要给自己添堵选NetCDF。两种格式的读取差异很简单# NetCDF import xarray as xr ds xr.open_dataset(era5_t2m_202001.nc) # GRIB ds xr.open_dataset(era5_t2m_202001.grib, enginecfgrib)注意如果使用GRIB需要先安装依赖pip install cfgrib并且系统里要有eccodes库conda install -c conda-forge eccodes。5.2 常见变量名与单位换算对照打开下载好的NetCDF文件后你会遇到一个新问题CDS表单里的变量名和NetCDF文件里的变量名对不上。比如你在网页里选的是2m_temperature文件里实际变量名却是t2m选的是total_precipitation文件里叫tp。这不是BUGCDS在后端做了短变量名映射。这里整理一份最常见的地表单层变量对照表CDS表单变量名NetCDF短变量名含义默认单位常用换算2m_temperaturet2m2米气温K减273.15得到℃total_precipitationtp总降水累积量m乘1000得到mmmean_sea_level_pressuremsl海平面气压Pa除以100得到hPa10m_u_component_of_windu1010米纬向风m/s无需换算10m_v_component_of_windv1010米经向风m/s无需换算surface_solar_radiation_downwardsssrd地表向下短波辐射J/m²除以3600得到W/m²小时平均2m_dewpoint_temperatured2m2米露点温度K减273.15得到℃气压层数据常见变量名更短t温度、z位势高度、r相对湿度、q比湿、u和v风的纬向和经向分量、w垂直速度。单位换算是新手最容易忽略的地方。ERA5的气温是开尔文降水的单位是“米”不是“毫米”辐射是焦耳每平方米而不是瓦每平方米。很多人画完图发现温度300多度、降水全是0.000几就是因为没做单位换算。我写处理脚本时习惯第一时间做单位换算并生成新变量比如import xarray as xr ds xr.open_dataset(era5_t2m_202001.nc) # 气温换算成摄氏度 ds[t2m_c] ds[t2m] - 273.15 # 降水从米换算成毫米 ds[tp_mm] ds[tp] * 1000这样后面统计、画图时就不用时刻记着原始单位了。5.3 处理ERA5的高频报错与排查思路用xarray处理ERA5时有四个报错是我遇到频率最高的这里统一复盘一下排查思路。第一个NetCDF打开报错提示Dataset is not a valid NetCDF file。大概率是下载的文件不完整或者其实是HTML错误页面被保存成了.nc后缀。你用文本编辑器打开文件看一眼如果开头是!DOCTYPE html说明服务器返回的是一个错误页面。这种情况通常是请求参数有问题或认证失效重新配置API Key后再下。第二个KeyError或变量名对不上。你以为变量叫t2m打开发现叫VAR2T之类多半是下载的数据产品选错了。注意区分reanalysis-era5-single-levels和reanalysis-era5-pressure-levels单层和气压层文件的变量命名逻辑完全不一样。先打印ds.data_vars看看实际变量名再写后续处理代码。第三个坐标顺序和范围奇怪。ERA5的经纬度坐标默认是递增排列纬度从-90到90。如果你要的区域跨了东西半球或者涉及日期变更线切区域时要注意经度范围可能是0到360也可能是-180到180。建议先打印ds.longitude.values和ds.latitude.values确认坐标排列再切片。第四个内存爆炸。xarray打开一个大NetCDF文件时用的是惰性加载看着很流畅但一旦做复杂计算、转为DataFrame内存立刻吃紧。处理方法有几种一是下载时就把区域缩小二是用xarray的sel、isel只切出研究区三是用.compute()配合Dask分块处理。最简单的还是从前端下载环节就控制好数据量这也是我前面反复强调区域和时间范围要收敛的原因。我自己现在的工作流基本固定成这样先用网页端对一个典型时段做一次小范围试探确认变量名、单位、坐标系统、文件大小都没问题然后把这个参数转成Python脚本按年份循环下载下载完立刻写一个检查脚本逐个打开文件检查大小、时间长度和缺测比例。这样一套流程下来数据质量和完整性基本就有保障了。ERA5下载这件事说到底是“参数设计”和“工具使用”的配合。网页端帮你理解参数API帮你提高效率。一开始别急着求多求全挑一个变量、一个区域、一个短时段完整跑通一遍后面再扩展到长序列、多变量的时候你会发现自己已经不会在下载环节浪费时间了。