做极地遥感和植被测高的朋友,对ICESat-2应该不陌生。2018年发射之后,它用ATLAS激光测高系统每天向地表发射光子,产出的数据文件动辄几百MB,很多人第一次接触“ICESat-2数据下载”时,第一反应是打开网页挨个点,结果几百个h5文件点到手酸,中途断网还得从头再来。我处理ATL08植被冠层高度数据时,最耗时间的不是模型跑批,而是怎么把几千个数据文件稳定地放到服务器上。这篇文章就专门聊ICESat-2数据下载的两种主流方法,适合需要批量获取数据的科研人员和相关领域的工程师参考。
1. 为什么ICESat-2数据下载会变成“技术活”
1.1 先弄清ICESat-2到底产出了哪些数据
ICESat-2全称是Ice, Cloud, and land Elevation Satellite-2,核心载荷ATLAS是一台单光子激光测高系统。和传统全波形激光雷达不同,ATLAS每秒发射一万个激光脉冲,每一个脉冲打到地面后返回的光子被单独记录,所以它能在轨道上同时测出6个波束的高程信息。数据产品从ATL01到ATL13覆盖了大气、陆地冰、海冰、海洋、内陆水、植被等多个领域,其中ATL03是所有产品的基础,记录所有光子事件的位置和时刻;ATL06是陆地冰高程产品;ATL08则是专门用于陆地植被冠层高度和地形高程的产品。
这些产品以HDF5格式存储,一个granule通常对应一个沿轨数据段,大小从几百MB到1GB不等。下载时并不是像FTP那样直接开个目录给你拉,而是需要通过NASA的Earthdata系统做身份认证,再经由CMR(Common Metadata Repository)元数据服务来检索和获取文件。换言之,ICESat-2数据下载本质上是一次“身份鉴权 + 元数据查询 + 对象存储访问”的组合流程,这也是它和很多普通数据网站下载体验不一样的地方。
1.2 两种下载方式的本质区别
目前主流下载方式可以分成两条路线。第一条是图形界面路线,打开Earthdata Search网页,按时间和空间框选数据,加入购物车后生成下载脚本;第二条是脚本化路线,使用Python库如earthaccess、icepyx直接检索和批量下载。
两者不是谁替代谁的关系。图形界面适合偶尔下载少量数据、想快速浏览数据集的情况,比如你只需要某一天某条轨道的几个文件,网页点几下就行。脚本化路线适合那种“今天下100个文件,明天更新10个新文件,下个月还要再拉一批”的生产场景,因为一次配置好账号和token之后,后续检索、下载、增量更新都能自动完成,还能把失败任务单独捞出来重试。理解了这两种路线的使用场景,再去看具体操作就不会迷茫。
1.3 下载前必须理解的授权机制
无论走哪条路线,都绕不开一个前置条件:Earthdata Login账号。你可以把它理解成整个NASA地球科学数据生态的“门禁卡”,ICESat-2数据托管在NSIDC DAAC(美国国家冰雪数据中心),访问它的数据前必须在Earthdata系统里完成账号注册,并授权给对应的数据分发中心。
实际操作中很多人卡在“明明登录成功,下载却报403”这一关,原因往往不是账号密码错了,而是没有在NSIDC DAAC完成额外授权。Earthdata系统支持多种授权应用,注册账号后还需要主动把NSIDC DAAC加入到已授权应用中,这一步不做,后续所有的自动下载脚本都会在鉴权环节失败。所以下面先花一点时间把账号、授权、token这些准备工作讲清楚,后面两种方法才能跑得顺畅。
2. 下载前的必备准备:账号、授权和凭据配置
2.1 注册Earthdata Login账号
注册流程不复杂,打开urs.earthdata.nasa.gov,进入注册页面,填写邮箱、姓名、机构信息即可。这里有几个容易踩坑的细节:邮箱一定要填长期使用的机构邮箱或稳定个人邮箱,因为后续token管理、密码找回都依赖它;机构信息对于科研用途来说不算强制,但建议认真填写,数据使用统计和问题反馈时会更有帮助。
注册完成后系统会发一封验证邮件,点击邮件里的链接激活账号。激活后建议立刻设置好强密码,因为后续你可能要把密码写进脚本或环境变量里,如果密码太弱,服务器上很容易被扫描爆破。我见过不止一个同学把NASA账号密码当成普通网站密码,结果服务器日志里出现大量异常登录尝试,最后不得不重置凭证。
2.2 给NSIDC DAAC开授权
登录Earthdata系统后,进入个人资料页面,找到“Applications”或“Authorized Apps”相关选项,列表中会出现需要授权的数据分发中心,比如NSIDC DAAC、GES DISC等。找到NSIDC DAAC后点击授权,系统会跳转到一个确认页面,提示你同意将账号与应用关联,点击同意即可。
这一步是ICESat-2数据下载最容易忽略的环节。如果跳过这个授权,earthaccess或icepyx在搜索数据时可能正常,但一旦开始下载,返回的HTTP状态码通常是401或403,日志里会提示access denied或者collection has restrictions。实际经验是,新注册的账号即使授权完成后,有些目录服务也存在几分钟到几小时不等的同步延迟,如果刚授权完就立刻下载却报错,等一段时间再重试往往就正常了。
2.3 生成Token并配置凭据
Earthdata系统支持两种常见的认证方式:一种是把账号密码写进.netrc文件,另一种是生成一个Token,在HTTP请求里通过Authorization请求头携带。对现代下载工具来说,Token方式更安全,也更容易管理,因为Token可以随时撤销,不用暴露密码。
生成Token的位置在Earthdata个人资料页,找到“Generate Token”按钮,点击后会生成一串字符串。很多教程建议你把Token直接粘贴到下载脚本中,但这在团队协作或服务器运维场景下并不安全。更稳妥的方式是把账号密码或Token写入环境变量,或者放在权限为600的.netrc文件中,这样脚本只读取环境变量,不把敏感信息写进代码仓库。
举个例子,如果用环境变量管理Earthdata账号,可以在用户的.bashrc或.zshrc里写入:
export EARTHDATA_USERNAME="your_earthdata_username" export EARTHDATA_PASSWORD="your_earthdata_password"然后执行source使其生效。注意:如果密码里有$、!、&等特殊字符,一定要用单引号包裹,否则会被Shell解释掉,导致登录时鉴权失败。
2.4 用curl快速验证连通性
在正式下载之前,我建议先用一条测试请求验证整条链路是否通。以ATL08产品为例,可以从CMR搜索接口拿到一个granule的下载链接,然后用curl带Token访问,看返回码是不是200。
命令行验证示例:
curl -L -o /dev/null -w "%{http_code}" \ -H "Authorization: Bearer YOUR_TOKEN" \ "https://daacdata.apps.earthdata.nasa.gov/file/xxxx.h5"如果返回200,说明账号授权、token、网络链路都没有问题,接下来无论是网页下载还是脚本下载,遇到鉴权问题的概率都会大大降低。这个“先验证再批量”的习惯在数据下载场景里非常有效,能帮你把鉴权问题和网络问题分开排查。
3. 方法一:在Earthdata Search网页端筛选并批量下载
3.1 根据经纬度和时间范围筛选数据
Earthdata Search的地址是search.earthdata.nasa.gov,打开后在搜索框里输入产品名,比如ATL08。页面会加载出地图和时空筛选工具,左侧面板可以设定时间范围,地图上有画框工具,能通过矩形框选空间范围。
这里有一点要注意:ICESat-2是沿轨观测,轨道在地图上表现为一条斜线,如果你只画一个很小的矩形,可能覆盖到的轨道段就很少,返回的granule数量自然少。所以筛选之前最好先大致了解目标区域的纬度范围和轨道重复周期,把空间范围适当放宽,宁可多下几个文件,也不要因为范围太紧遗漏数据。时间筛选同理,如果只需要某个季节的数据,直接把起止日期填进去就行,Earthdata Search会自动计算符合条件的轨道时间。
3.2 加入购物车并生成下载脚本
筛选完成后,页面会列出所有匹配的granule,可以直接勾选,也可以一键全选,然后点击“Add to Cart”。购物车右上角会出现文件数量和预估体积,确认无误后进入购物车页面,点击“Download”会进入一个数据访问授权页面,确认账号已授权NSIDC DAAC后,系统会生成一段下载脚本。
生成的脚本通常是基于wget或curl的,文件内容看起来是一堆带鉴权头的URL。把它下载下来保存成download.sh,然后放到你想要存放数据的目录中执行。
3.3 拿到脚本后的正确运行姿势
下载脚本需要在已经认证过的环境中运行。如果你没有把账号密码写入.netrc,也没有设置环境变量,直接运行脚本大概率会报403错误。比较省心的方法是在服务器上先配置好Earthdata登录信息,最简单的做法是在home目录下创建.netrc文件:
machine urs.earthdata.nasa.gov login your_username password your_token_or_password创建后立刻执行chmod 600 ~/.netrc,把权限收紧,避免其他用户读到敏感信息。然后执行:
bash download.sh脚本会逐个请求文件,下载过程中如果某个文件失败,可以重新运行脚本,wget或curl配合断点续传参数能跳过已经完成的部分。比如wget加-c参数,curl加-C -参数。网页生成的脚本不一定自带这些参数,拿到手后手动加上就行。
3.4 图形界面下载的局限性
网页方式最大的问题在于不适合规模化数据管理。一方面,如果数据量很大,网页生成的脚本是一长串URL列表,运行一次可能要几天,中途一旦服务器重启或断网,断点续传虽然能续,但要重新解析脚本、筛选未完成的文件,比较繁琐。另一方面,网页方式难以做增量更新。比如你每周要拉一次最新数据,每次都去网页手动框选再生成脚本,重复劳动不说,还容易遗漏。
所以说,这条路线适合临时、小批量、探索性下载。一旦你确认某个区域某个时间段的数据是要长期使用的,建议直接切换到脚本化下载,下面展开说。
4. 方法二:用Python脚本批量下载工业化数据
4.1 为什么推荐earthaccess和icepyx
Python生态里目前有两个库对ICESat-2数据下载支持得最好。第一个是earthaccess,它是NASA地球数据云生态里的通用访问库,底层封装了CMR检索、Earthdata登录、云端数据下载等功能,只要是NASA Earthdata体系内的数据产品都能用,接口设计得也很简洁。第二个是icepyx,它是专门为ICESat-2数据设计的工具库,在earthaccess基础上又封装了产品格式、轨道网格等面向ICESat-2的特殊逻辑,写起来更贴近测高数据的处理习惯。
如果你想同时下载ATL03、ATL06、ATL08等多种产品,或者以后还可能接触其他NASA数据,直接学earthaccess比较划算。如果你整个项目周期内就围绕ICESat-2产品打转,用icepyx会更顺手。两者在底层共享Earthdata认证体系,所以前面配置的环境变量对它们都有效。
4.2 安装与环境配置
安装很简单,执行:
pip install earthaccess icepyx安装完成后,确保环境变量EARTHDATA_USERNAME和EARTHDATA_PASSWORD已经设置好。earthaccess在启动时会自动读取这两个变量,如果没有设置,它会弹出一个交互式输入框,让你在终端里输入用户名和密码,这在服务器后台运行时不太方便,因此还是推荐提前写好环境变量。
另外要注意Python版本,建议使用3.9及以上版本,这两个库对较老的Python版本支持不太好。如果是在集群上运行,最好用虚拟环境安装,避免和系统自带的Python包冲突。
4.3 earthaccess快速下载示例
earthaccess的标准使用流程是登录、搜索、下载三步。下面这段代码演示了如何搜索某个区域、某段时间的ATL08数据,并批量下载到本地目录:
import earthaccess # 登录Earthdata,会自动读取环境变量 earthaccess.login() # 在黄石公园附近搜索2019年3月的ATL08数据 results = earthaccess.search_data( short_name="ATL08", bounding_box=(-111.0, 44.5, -109.5, 45.0), temporal=("2019-03-01", "2019-03-31"), count=20, ) print(f"搜索到 {len(results)} 个数据文件") # 批量下载 files = earthaccess.download(results, "./atl08_201903") print(f"已下载 {len(files)} 个文件")这里的bounding_box顺序是西经、南纬、东经、北纬,也就是四个数字分别对应矩形框的左、下、右、上边界,写反了会搜到完全不相关的区域。temporal用起止日期字符串组成的元组,特别适合做增量更新:下次想下载新数据,只需把起始日期改成上次下载的日期。
4.4 icepyx的查询与下载示例
icepyx的写法更贴近ICESat-2产品使用习惯,它把空间范围、时间范围、产品名做成了Query对象,调用方式很直观:
import icepyx as ipx # 构建查询对象 region = ipx.Query( "ATL08", [-111.0, 44.5, -109.5, 45.0], ["2019-03-01", "2019-03-31"], ) # 登录Earthdata region.earthdata_login( uid="your_earthdata_username", email="you@example.com", ) # 查看有哪些可用的granule region.avail_granules() # 下载所有granule到指定目录 region.download_granules("./atl08_201903")icepyx里的earthdata_login方法需要传入用户名和邮箱地址,这和我前面说到的Earthdata账号注册信息是一致的。avail_granules()会把可下载的数据文件清单打印出来,方便你确认数据范围;download_granules()则会自动完成登录态的传递和文件下载。这个库还会在下载之前检查本地已存在的文件,避免重复下载,对断线重连场景比较友好。
4.5 批量下载中的工程化细节:断点、重试、日志
用脚本自动下载时,不能只把download函数一跑就撒手不管,特别是数据量过万时,网络波动、服务端限流、磁盘写满都会导致任务中途失败。下面几个工程细节是我在实践中验证过很有效的做法。
第一,分批次下载。不要一次把一整年的数据全部拉下来,建议按月或按轨道段分目录,这样即使某个批次失败,也不会影响其他批次,排查问题也方便。第二,保留下载日志。无论是earhaccess还是icepyx,直接print输出都不利于事后追溯,可以自己用Python的logging模块把每次下载的文件名和结果写到日志文件里。第三,对于失败的下载,可以用循环重试,但最多不要超过3次,重试间隔从5秒、30秒、120秒逐步增加,避免对服务端造成压力。第四,如果并发下载,用线程池控制在4到8个并发度,太高容易被服务端限流,太低则浪费带宽资源。
5. 一次完整实操:从零下载2019年春天的ATL08数据
5.1 规划下载范围
为了把过程串起来,这里以美国黄石国家公园附近为例,模拟一个真实任务:需要2019年3月1日到3月31日之间,范围在(-111.0, 44.5)到(-109.5, 45.0)内的ATL08植被冠层高度数据。
为什么要选这片区域?黄石地区纬度适中,森林覆盖度和地形起伏都比较有代表性,ATL08在处理森林冠层高度时效果受地形和植被密度影响,这类数据对于做生态遥感的朋友来说很有参考价值。当然,具体经纬度范围你可以按自己的研究区调整。
5.2 用icepyx跑数据清单
在配置好环境变量和授权之后,直接运行上面那段icepyx代码。它会先展示搜索到的granule数量、每一条数据的文件名和时间覆盖范围。ICESat-2轨道的重复周期大约是91天,所以3月份内该区域可用的轨道次数不会很多,搜索出来的文件数量一般在一批可管理的范围内。
avail_granules()的结果可以导出成列表,方便做后续处理。我在实际任务中会把清单保存成csv文件,记录文件名、文件大小、轨道号,这样万一下载中断,我可以用这些信息去检查缺失的文件,有针对性地重下,而不是盲目全部重跑。
5.3 下载并校验文件
执行download_granules后,数据文件会陆续写入指定目录。下载完成后不要立刻认为万事大吉,建议对文件做一轮完整性检查。最简单的方式是确认文件大小符合预期,HDF5文件如果下载不完整,文件大小往往明显偏小。更严格的方式是用h5py读取文件,尝试打开并访问关键数据集:
import glob import h5py files = glob.glob("./atl08_201903/*.h5") for fpath in files: try: with h5py.File(fpath, "r") as f: lat = f["/latitudes"][:] lon = f["/longitudes"][:] print(fpath, "OK", lat.shape) except Exception as e: print(fpath, "FAILED", e)这段代码把每个h5文件都打开一遍,并读取经纬度数据集,如果文件损坏或下载不完整,会在这一轮暴露出来。对于ATS08数据,第一次跑可能几秒钟就打不开,那就说明该文件需要重新下载。
6. 常见问题与排查技巧实录
6.1 登录或授权相关
现象是earthaccess.login()后提示用户名或密码错误,但网页登录又是正常的。这种情况多半是环境变量里的用户名或密码包含了特殊字符,Shell在读取时做了转义。解决方案是用单引号包裹整个字符串,或者在Python代码里用getpass手动输入一次,确认无误后再写进环境变量。
现象是搜索数据正常,下载时报403或401。前面说过,这通常是NSIDC DAAC授权没有完成。去Earthdata个人页面的Applications里检查一下NSIDC DAAC是否在已授权列表中。如果显示已授权,仍然报错,可以撤销授权再重新授权一次,往往能解决同步延迟问题。
6.2 下载中断或网络问题
大批量下载时,最常见的情况是下载了一部分文件之后突然停止,重新运行脚本时提示文件已存在不重下,但实际上留在磁盘上的是不完整的文件。这个坑很隐蔽,因为有些下载库判断重复文件时只看文件名,不看文件大小。解决办法是在下载之前设置覆盖策略,或者先按文件大小过滤一遍本地文件,把明显偏小的部分重命名或删除后再跑。
如果下载速度特别慢,可以换个时间段再试。NASA数据分发服务在北美白天时段请求量比较大,国内用户访问有时会觉得速度不稳定,这属于正常现象。脚本化下载的好处就在于它可以后台慢慢跑,下载一批算一批,不必集中在一段时间内完成。
6.3 脚本执行报错或语法问题
网页生成的下脚本里有时会出现换行符不一致的问题,尤其是从浏览器直接复制到Windows再传到Linux服务器时,容易带上\r\n,导致Shell解析出错。遇到这种情况,在Linux下执行:
sed -i 's/\r$//' download.sh把回车符清理掉再执行。还有一种情况是脚本里用到了较新的wget或curl参数,老版本不支持,可以在运行前用wget --version或curl --version确认版本,必要时升级到较新版本。
6.4 数据文件命名和元数据匹配问题
下载下来的文件名格式通常是ATL08_年月日时分秒_轨道号_版本号_编号.h5,看起来数值很多,但其实每个字段都有明确含义。遇到需要按轨道匹配资料时,可以直接从文件名里解析出轨道号和日期,不需要打开文件。有些用户下载后发现文件名与搜索时看到的清单不一致,这种概率很低,一旦出现,建议直接把本地文件名和CMR返回的链接中的文件名对一遍,以链接中的文件名为准。
6.5 磁盘空间和文件清理策略
HDF5文件大小经常在几百MB左右,一批数据下下来动辄几十GB。下载前先检查好磁盘容量,并给临时目录留出至少等于数据量2倍的空间,因为下载过程中可能存在临时文件和校验缓存。如果磁盘吃紧,建议按年份或轨道段分目录存储,已经处理完的数据及时转存到移动硬盘或对象存储,避免服务器磁盘长期处于高水位状态。
7. 一点实际操作中的个人体会
最后分享一点我个人在ICESat-2数据下载项目里的体会。最开始我也习惯用网页方式下载,觉得看着进度条心里踏实,但当需要处理几百个文件时,网页方式马上就不够用了。后来切换到earthaccess和icepyx,通过脚本统一管理,我才能把更多精力放在数据处理和质量校验上。
如果你打算长期使用ICESat-2数据,我强烈建议花一天时间把earthaccess这套流程熟悉起来,它不仅能解决ATL08,还能顺带处理其他NASA地球数据产品。下载时记得做好分批、日志、校验这三件事,数据规模再大也不会让人崩溃。希望这篇内容能帮你少踩一些坑,顺利拿到自己需要的数据。