ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

InSAR数据下载坑与救场:用wget稳定拉取Sentinel-1 Burst

2026/9/20 13:08:17 拓冰建站 浏览量
InSAR数据下载坑与救场:用wget稳定拉取Sentinel-1 Burst 干了这么多年InSAR说实话最消耗耐心的工作往往不是算法调参反而是下载数据这一关。最近处理一批哨兵一号Sentinel-1的IW模式SLC数据目标是做矿区形变时间序列重点只看其中几个burst。下载过程折腾了一整天先是被aria2c的连环报错搞得怀疑人生后来静下心写了个wget脚本把问题全解决了。这篇把踩坑记录和救场过程整理出来给准备碰Sentinel-1 Burst数据的朋友当个参考。1. 问题起因从Burst处理说起1.1 为什么要单独挑Burst来折腾哨兵一号的干涉宽幅IW模式一景SLC数据在距离向上分成三个swath每个swath又沿方位向切成若干burst。以IW1为例通常有9个左右的burstIW2和IW3也类似。做InSAR处理时多数情况下并不需要整景数据全部参与计算尤其是研究区只有几百平方公里的小范围往往只需要覆盖目标区域的几个burst就足够了。这个特性在实际工程中非常重要。我在处理矿区形变时研究区大致落在某一个track的固定范围内如果下载整景SLC单景数据量在5到8GB之间时间序列一拉就是几十景磁盘和内存压力都很大。而使用ASF的Burst搜索功能可以直接定位到研究区命中的burst切片这类Burst SLC产品体积小很多通常一个burst文件在几百MB到1GB左右下载和处理效率能提升一大截。不过下载burst数据有个前提你得先从ASF Vertex或者哥白尼数据空间把这些数据源整明白并且能稳定地把文件拉下来。这里恰恰是很多人第一次卡住的地方。1.2 数据下载场景下个数据怎么成了灾难很多人对卫星数据下载的印象还停留在浏览器里点个链接等进度条走完。但命令行下载Sentinel-1数据是完全不同的体验。ASF Vertex提供的下载链接本质上是S3的临时签名链接预签名URL链接里带了一长串签名参数有一定有效期一般几小时到一天不等。这个链接一旦过期不管用什么工具都下载不了。哥白尼数据空间Copernicus Data Space的机制又不一样它走的是OAuth 2.0授权流程命令行下载需要先请求一个Bearer Token再在HTTP请求头里带Authorization: Bearer xxx才能访问产品。这两个平台我都用它们的鉴权方式决定了命令行下载工具必须能灵活设置请求头、User-Agent以及会话恢复参数。如果只是下载单个文件浏览器下载就够了。可一旦进入批量下载阶段比如二十景SLC、几十个burst文件手工点连接完全不可行必须用脚本批量拉取。这时候工具选型就成了第一个坑。2. aria2c翻车实录报错现象与根因拆解2.1 我实际遇到的报错现场我最初的方案是用aria2c配合多线程下载理由很简单aria2c支持16线程分片下载速度理论上比单线程wget快得多。结果在ASF上下载burst数据时刚开始几个文件还挺顺利到第4个文件就频繁出现这种报错GnuTLS: Error in pull function. Download GID#xxxx status: error当时我还以为是临时网络波动于是加了--max-tries和--retry-wait重试参数结果问题更严重了——连接数一旦上去部分文件直接返回403 Forbidden还有几个文件下载到30%左右就卡死日志里反复出现连接重置。把同样的URL复制到浏览器里秒下用wget单线程下载也能顺利跑完。这个结果让我确信问题不在服务器而在aria2c发请求的方式上。后来我抓了aria2c的请求头和浏览器请求头对比发现aria2c默认的User-Agent是aria2/1.36.0而一些CDN边缘节点对非浏览器User-Agent的请求非常敏感直接拒绝连接或者强制要求验证。2.2 根因拆解这不是工具差是“会话”不对aria2c本身是个非常强大的下载工具但它默认参数是为「通用文件下载」设计的面对卫星数据平台这种带鉴权、限速、签名链接的下载场景容易出现几个典型的“会话不匹配”问题。第一是User-Agent问题。ASF的CloudFront或S3签名链接对请求头里的User-Agent其实没有硬性白名单但哥白尼数据空间的API网关不同它会根据User-Agent判断是不是合法的客户端工具。用默认aria2c头去请求服务器返回403或者XML格式的错误页面非常常见。第二是Range请求过多。aria2c的多线程需要在同一文件上发起多个分片Range请求S3预签名URL的签名是基于完整对象路径的本身支持Range但Copernicus Data Space这类平台对单文件的并发分片请求有限制。线程数调到8到16以后很容易触发服务器的限流机制表现为连接被重置、下载中断、甚至返回Too Many Requests。第三是TLS库兼容问题。aria2c在Linux发行版里一般链接的是GnuTLS不同版本在处理HTTP/2连接时偶尔会抽风尤其当服务器强制HTTP/2时GnuTLS: Error in pull function这种错误就冒出来了。wget虽然也会用GnuTLS但它的错误处理更保守会自动回退到HTTP/1.1反而更加稳定。2.3 为什么我之前执着于aria2c我得承认我一度很迷信aria2c原因就是快。在下载大型通用文件时16线程分片下载确实能跑满带宽测速软件里看着特别爽。但对于Sentinel-1这种专业数据下载稳定性远大于极限速度因为下载失败导致的返工成本太高了。另外aria2c同时管理多个并发任务的机制在面对几十个URL时确实方便--input-fileurls.txt一行一个链接全自动调度。这个设计思路没问题问题在于它默认的“高并发、激进重试”策略和卫星数据平台的“温和限速、严格鉴权”策略正好撞车。所以遇到连续报错时不要急着提高线程数先把请求头、会话、重试策略都按平台规矩调整好再考虑速度。提示如果你的aria2c已经能稳定下载不需要强行换工具。这里只是记录我在特定数据平台上碰到的情况。不同平台、不同时期的服务端策略会有差异遇到报错先抓源因才是关键。3. 为什么wget能救场脚本化重试与容错设计3.1 wget的“笨功夫”反而可靠wget这个工具在下载圈里被很多人嫌弃觉得它单线程、速度慢、界面朴素。但它的可靠性和可脚本化能力在数据下载场景里是真正的刚需。wget有几个核心参数几乎每一条都踩在我的痛点上wget -c --tries5 --retry-connrefused --waitretry10 --timeout30 --user-agentMozilla/5.0 ...-c是断点续传文件下载一半断了下次继续不用重新开始。--tries5是失败重试次数--retry-connrefused让它在连接被拒绝时继续重试--waitretry10控制重试间隔避免连续请求被封。--timeout30则是设置超时时间避免服务器没响应时一直挂死。这套参数组合下来wget的行为就变得非常“稳定”单线程老老实实地下载断了就续传遇到临时网络抖动就等一会儿再试。虽然单文件速度不如aria2c的多线程但整体成功率非常高几十个文件跑下来基本不需要人工干预。3.2 写一个能自动重试的bash批量下载脚本接下来是救场的关键写一个批量下载脚本把登录鉴权、下载、重试、校验、日志都封装起来。这个脚本用bash写的依赖工具只要wget和标准shell组件就行任何Linux发行版都有。下面是我用ASF临时链接批量下载burst数据的脚本示例#!/bin/bash # 批量下载Sentinel-1 Burst数据脚本 URL_FILEurls.txt LOG_FILEdownload.log ERROR_LOGdownload_error.log RETRY_COUNT5 UAMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36 download_file() { local url$1 local filename$(basename $url | cut -d? -f1) if [ -f $filename ] [ -s $filename ]; then echo [SKIP] $filename exists | tee -a $LOG_FILE return 0 fi echo [BEGIN] $filename | tee -a $LOG_FILE wget -c \ --user-agent$UA \ --tries$RETRY_COUNT \ --retry-connrefused \ --waitretry10 \ --timeout30 \ --no-check-certificate \ -O $filename \ $url $LOG_FILE 21 local exitcode$? if [ $exitcode -ne 0 ]; then echo $url $ERROR_LOG echo [FAIL] $filename exit$exitcode | tee -a $LOG_FILE return 1 else echo [OK] $filename | tee -a $LOG_FILE return 0 fi } while IFS read -r url; do [ -z $url ] continue download_file $url done $URL_FILE这个脚本的处理逻辑是先判断文件是否已经存在且非空存在就跳过充分利用断点续传然后调用wget下载失败就记录到错误日志等全部跑完后统一排查重试。实际用下来一晚上挂在后台第二天早上二十几个burst文件全部就位基本没有需要手动处理的。3.3 登录与鉴权Cookie和Token处理是关键使用ASF下载时预签名URL本身就包含权限信息不需要额外处理wget脚本里加不加Cookie问题不大。但哥白尼数据空间必须要有Token这就需要在脚本里再加一层鉴权逻辑。Token的获取方式很简单先用账号密码请求一个OAuth Token然后再用Token去下载# 获取Token TOKEN$(curl -s -X POST https://identity.dataspace.copernicus.eu/auth/realms/CDSE/protocol/openid-connect/token \ -H Content-Type: application/x-www-form-urlencoded \ -d grant_typepasswordusername你的用户名password你的密码client_idcdse-public \ | python3 -c import sys,json; print(json.load(sys.stdin)[access_token])) # 下载时携带Authorization请求头 wget -c \ --headerAuthorization: Bearer $TOKEN \ --tries5 \ --retry-connrefused \ -O Sentinel1_SLC.zip \ https://catalogue.dataspace.copernicus.eu/odata/v1/Products(...)/$value哥白尼数据空间的OData接口返回的下载链接是$value结尾必须在请求头里带Token才能访问。这里有个坑Token有有效期通常一小时左右批量下载几十个文件如果耗时超过有效期后半段的请求就会401。处理方式是写一个Token过期检测遇到401时刷新Token再继续或者干脆把整个下载过程控制在Token有效期内。3.4 下载完整性校验下载成功不等于文件没问题。我在ASF平台下载burst数据时一般手动校验文件大小和checksum。ASF在每个下载产品旁边会提供对应的checksum文件使用.md5或.sha256格式可以用下面的命令核对# 检查单个文件MD5 md5sum -c 20250101_IW1_SLC_BURST.md5 # 批量检查当前目录下所有zip for f in *.zip; do md5sum $f checksums.txt done如果是从哥白尼数据空间下载的SLC平台不直接给checksum但可以对照平台页面上标注的产品大小再用ls -l对比本地文件字节数一致一般就没问题。为了保险我还会在脚本里加一步大小判断下载完自动比较预期大小和实际大小不匹配就自动重下。这一步在批量下载时能省下很多人工检查的时间。4. 完整实操流程从拿到下载链接到校验完成4.1 第一步在ASF Vertex检索Burst并生成下载清单进入ASF Vertex网站后先切换到Search页面在Dataset里勾选Sentinel-1Beam Mode选IWPolarization选VVVH或者你自己需要的极化方式。然后通过多边形工具框选研究区设置时间范围、轨道方向、相对轨道号等条件。重点是使用Burst搜索选项。ASF支持在搜索前勾选“Burst”这样搜索出来的结果就是按burst切片的产品而不是整景SLC。搜索结果列表里每个条目对应一个burst文件文件名类似S1A_IW_SLC__1SDV_20250101T..._20250101T..._0XXX_BURST。勾选需要的burst加入下载列表。在下载列表里ASF提供几种导出方式我习惯点击Download按钮旁边的小箭头选择CSV把包含所有预签名URL的清单下载下来。CSV文件里有URL列后续脚本直接从这列提取链接即可。4.2 第二步从CSV提取链接并启动下载脚本CSV文件通常包含头部和很多元信息字段直接用cut或者awk提取URL列# 假设URL为第5列根据实际CSV表头调整 cut -d, -f5 download_manifest.csv | sed s///g urls.txt然后用前面写好的download.sh启动批量下载。实际跑的时候我建议先在终端前台跑两三个文件确认没有权限问题、没有烧CPU的异常再放进screen或tmux后台跑。chmod x download.sh ./download.sh跑完以后检查download_error.log把里面的失败URL单独保存再次执行脚本即可重下。提示预签名URL有时效性。如果下载清单生成后没有及时开始下载中途链接过期导致403不要去调wget参数回到ASF重新生成一份新清单把过期链接替换掉再跑速度更快。4.3 第三步并发控制与资源管理wget单线程稳定但几十个文件串行下载确实慢。我的折中方案是用xargs开2到3个并发而不是无限拉高并发数cat urls.txt | xargs -P 3 -I {} ./download_one.sh {}其中download_one.sh就是上面脚本里下载单个文件的函数单独抽出来的版本。2到3个并发是我在实际使用中比较稳妥的选择。并发太高容易触发ASF的速率限制反而大面积失败并发太低几十个文件又要等很久。2到3个并发可以把带宽利用起来又不太会被封。磁盘空间方面burst数据每个文件约0.5到1.5GB如果是完整SLC一景基本上5GB往上走。下载前确认df -h查看磁盘余量建议保留目标文件总大小的2倍以上空间因为解压、切片、干涉处理时还会有临时文件产生。4.4 第四步目录整理与SNAP对接下载好的burst文件我按区域/日期/轨道建目录文件名保留原始命名规则。SNAP可以直接读取这些zip格式的burst SLC数据不需要提前解压在SNAP里通过Product Reader识别并读取。如果是完整SLC数据在SNAP里做InSAR的一般流程是先做S-1 TOPSAR Split把目标burst裁剪出来再执行Deburst拼接相邻burst。这里有个经验下载整景时其实包含了所有burst但我们在SNAP里Split时只选研究区对应的几个burst能大幅减少后续干涉、滤波、解缠的计算量。我实测过同一景数据只处理目标burst比全swath处理能节省40%到60%的时间这对大批量数据非常重要。5. 常见问题与排查速查表5.1 下载失败问题速查下面这张表是我在实际下载Sentinel-1数据过程中遇到过的典型问题、判断方法和处理办法按出现频率排序现象可能原因排查方法解决办法403 ForbiddenURL过期或请求头被拦截在浏览器打开URL测试重新生成下载清单添加具体User-AgentGnuTLS Error / SSL连接中断服务器强制HTTP/2与aria2c的GnuTLS兼容问题用wget下载同URL测试换用wgetaria2c加--disable-http-keepalive连接重置 / Connection reset多线程并发过高触发限流减少并发线程数线程数调整为1到3加--retry-connrefused下载到一半卡死网络波动或服务器响应超时查看wget日志是否重试次数耗尽用-c断点续传提高--tries和--timeout文件大小与平台显示不一致下载中断后被错误保存比较平台产品大小删除文件重新下载或运行校验检查Token过期导致401下载耗时超过Token有效期查看日志是否出现401脚本检测到401后重新获取Token并重试wget报“无法解析主机地址”本地DNS问题或防火墙拦截试ping数据平台域名检查DNS、代理设置必要时配置代理5.2 aria2c用户如何快速调整参数如果你还是更倾向用aria2c并不需要完全放弃只需要针对下载平台调整几个参数。从ASF下载时可以尝试把User-Agent设成浏览器常见值关闭多线程分片以单连接模式运行aria2c -x 1 -s 1 \ --user-agentMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 \ --file-allocationnone \ --max-tries5 \ --retry-wait10 \ --continuetrue \ --input-fileurls.txt从哥白尼数据空间下载时通过--header传入Tokenaria2c -x 1 -s 1 \ --headerAuthorization: Bearer $TOKEN \ --continuetrue \ 下载URL实测下来把-x和-s都设为1aria2c本质上就变成了一个支持断点续传的单线程下载器稳定性会和wget接近。但既然绕了一圈又回到单线程我自己干脆直接用wget少一层工具的复杂度。5.3 下载过程中的独家小技巧最后补充几个实用小技巧都是我在实际批量下载中总结的。下载日志一定要保留。尤其当几十个文件跑完以后你不可能记住哪个文件成功、哪个失败。脚本里把[OK]、[FAIL]、[SKIP]输出到日志文件跑完以后用grep过滤一下就能快速统计grep -c \[OK\] download.log grep \[FAIL\] download.log下载清单里的URL如果包含?签名参数在basename取文件名时一定要截掉?后面的部分否则文件名会带着一长串参数。上面脚本里用了cut -d? -f1这个细节能避免生成一堆奇怪命名的文件。批量下载尽量固定在夜间执行。卫星数据平台的服务器在白天高峰期流量大限流策略更严格晚上和凌晨的下载成功率明显更高。这不是玄学是CDN带宽资源分配的实际情况。还有一个容易被忽视的点下载机的时间要同步。ASF和哥白尼数据空间的签名称URL里都带时间戳本地时间偏差太大会导致签名校验不通过表现症状就是403。遇到一直403时不妨先ntpdate同步一下系统时间。6. 从下载到Burst处理绕不开的坑下载问题解决后Burst处理本身还有几个绕不开的环节这里简单提一下给初次接触的朋友一个预期。Burst数据在SNAP里的核心操作是S-1 TOPSAR SplitDeburst。Split是沿方位向裁剪出目标burstDeburst是把相邻burst无缝拼接起来消除burst之间的重叠区。这两个操作对原始数据质量非常敏感但更常见的问题是两个影像的burst编号不匹配做干涉时软件会报错提示主影像和辅影像的burst索引对不上。这种情况多发生在跨轨、跨日期影像对或者使用了不同子swath的数据。解决办法是检查两个SLC的burst坐标信息确保都对应同一绝对轨道位置。在SNAP里可以通过查看两个产品的Annotation信息对比burst起始时间一般要求主辅影像的burst时间范围高度重叠否则干涉图会出现明显的断层条纹。另外轨道文件也很关键。SNAP下载精密轨道星历文件有时会因为网络原因失败后续做轨道精化和形变反演出问题。批量下载数据的同时我一般顺手把对应轨道文件也拉下来放到SNAP默认的辅助数据目录里避免处理时临时下载失败。写在最后的一点体会这一趟从aria2c连环报错到wget脚本救场折腾下来最大的感受是命令行下载工具没有绝对的好坏关键是匹配你所在平台的规则。高并发多线程在下载通用大文件时确实爽但卫星数据平台通常对接了CDN、签名鉴权、限流策略这种情况下“慢而稳”反而更高效。我现在的标配是ASF数据用wget脚本Copernicus数据空间用带Token的wget脚本并发数控制在3以内下载前先看磁盘下载后做校验日志留全。这套流程虽然朴素但跑了几百个文件没出过岔子。如果你是刚开始处理Sentinel-1数据建议第一次批量下载前先拿五个文件做小范围测试确认整个链路没问题再放开跑能避免很多半夜被报警短信叫醒的尴尬。