前言

下载Sentinel数据需要到欧空局的专门网站,划定区域、设置日期等等参数,然行进行检索。检索完成后选择需要下载的影像进行下载。如果需要下载大量影像数据,尤其是长时间序列的数据,这种方式比较麻烦。

欧空局发布了sentinelsat的pyhton包,可以进行调用。

IDM也有对应的包,可以进行调用。

那么使用这个两个包基本可以实现快速、自动化、批量下载。

sentinelsat—Sentinel的Python API

这里是说明文档。

Python API — Sentinelsat 1.2.1 documentation

我们主要使用query函数,进行所需要数据的检索。

先将索引到的结果写出为excel表格。url即下载地址。拖到IDM中即可下载。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
def Search_data(login, key, path_geojson, start_date, end_date, name, product_type, cloud, filepath):
"""
:param login: 欧空局账号,字符串类型
:param key: 欧空局密码,字符串类型
:param path_geojson: 兴趣区路径及文件名
:param start_date: 开始时间,字符串
:param end_date: 结束时间,字符串
:param name: 卫星名称
:param product_type: 卫星类型
:param cloud: 云量筛选,格式:(0,15)
:param filepath: Url保存路径及文件名
:return: 返回存有下载链接的excel路径
"""
api = SentinelAPI(login, key, 'https://scihub.copernicus.eu/dhus')
# 登陆账号https://scihub.copernicus.eu/apihub/
footprint = geojson_to_wkt(read_geojson(path_geojson))
# 读取兴趣区,兴趣区由http://geojson.io导出
products = api.query(footprint,
date=(start_date, end_date), # 搜索的日期范围
platformname=name, # 卫星平台名,Sentinel-2
producttype=product_type, # 产品数据等级,Sentinel-2: S2MSI2A,S2MSI1C,S2MS2Ap/Sentinel-1:SLC,GRD,OCN
cloudcoverpercentage=cloud) # 云量百分比
# 搜索A、B双星的数据
row = 0
workbook_write = xlwt.Workbook(encoding='utf-8')
worksheet_write = workbook_write.add_sheet('Url_image')
for product in products:
# 通过for循环遍历并打印、下载出搜索到的产品文件名
info_product = api.get_product_odata(product)
# 通过OData API获取单一产品数据的主要元数据信息
worksheet_write.write(row, 0, info_product['url'])
worksheet_write.write(row, 1, info_product['title'])
print(info_product['title'])
# print(product_info['url'])
# 打印下载的产品数据文件名,id/uuid代码编号,size数据大小,title标题,url链接,md5,date时间
# api.download(product)
row += 1
workbook_write.save(filepath)
return filepath, api
# 循环结束后,保存表格

subprocess—IDM的Python api

官方说明文档

https://www.internetdownloadmanager.com/support/command_line.html

简单总结下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
使用:
idman /s

idman /d URL [/p local_path] [/f local_file_name] [/q] [/h][/n] [/a]
可以进行下载
参数解释:
/d URL #根据URL下载文件
/s #开始下载队列中的任务
/p #定义文件要存储在本地的地址
/f #定义文件存储在本地的文件名
/q #下载成功后IDM将退出。
/h #下载成功后IDM将挂起你的链接
/n #当IDM不出问题时启动静默模式
/a #添加指定文件到/d的下载队列,但是不进行下载

演示下步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from subprocess import call 

# IDM安装路径下面的exe文件
IDM = r"D:\IDM\Internet Download Manager\IDMan.exe"

# 下载路径
DownPath = 'D:/下载/'

# 下载文件名称
local_file_name = 'xx'

# 下载文件链接(注意是这个列表)
urlList = ['xxx']
# 将下载链接全部加入到下载列表,之后再进行下载。
for ul in urlList:
call([IDM, '/d', ul, '/p', DownPath, '/f', local_file_name, '/n', '/a'])
call([IDM, '/s'])

具体步骤

  1. 根据需求检索数据,导出下载链接
  2. 调用IDM批量下载

全部代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# -*- coding: utf-8 -*-
"""
@Time : 2023/3/31 15:35
@Auth : RS迷途小书童
@File :Batch download of Sentinel data.py
@IDE :PyCharm
@Purpose :批量下载哨兵数据
"""
from sentinelsat import SentinelAPI, read_geojson, geojson_to_wkt
# 导入用户登录,兴趣区识别模块
from subprocess import call
# 用来唤醒IDM下载数据
from datetime import date
import time
import xlwt
import xlrd2
# excel的读取和写入模块
from tqdm import tqdm


def Search_data(login, key, path_geojson, start_date, end_date, name, product_type, cloud, filepath):
"""
:param login: 欧空局账号,字符串类型
:param key: 欧空局密码,字符串类型
:param path_geojson: 兴趣区路径及文件名
:param start_date: 开始时间,字符串
:param end_date: 结束时间,字符串
:param name: 卫星名称
:param product_type: 卫星类型
:param cloud: 云量筛选,格式:(0,15)
:param filepath: Url保存路径及文件名
:return: 返回存有下载链接的excel路径
"""
api = SentinelAPI(login, key, 'https://scihub.copernicus.eu/dhus')
# 登陆账号https://scihub.copernicus.eu/apihub/
footprint = geojson_to_wkt(read_geojson(path_geojson))
# 读取兴趣区,兴趣区由http://geojson.io导出
products = api.query(footprint,
date=(start_date, end_date), # 搜索的日期范围
platformname=name, # 卫星平台名,Sentinel-2
producttype=product_type, # 产品数据等级,Sentinel-2: S2MSI2A,S2MSI1C,S2MS2Ap/Sentinel-1:SLC,GRD,OCN
cloudcoverpercentage=cloud) # 云量百分比
# 搜索A、B双星的数据
row = 0
workbook_write = xlwt.Workbook(encoding='utf-8')
worksheet_write = workbook_write.add_sheet('Url_image')
for product in products:
# 通过for循环遍历并打印、下载出搜索到的产品文件名
info_product = api.get_product_odata(product)
# 通过OData API获取单一产品数据的主要元数据信息
worksheet_write.write(row, 0, info_product['url'])
worksheet_write.write(row, 1, info_product['title'])
print(info_product['title'])
# print(product_info['url'])
# 打印下载的产品数据文件名,id/uuid代码编号,size数据大小,title标题,url链接,md5,date时间
# api.download(product)
row += 1
workbook_write.save(filepath)
return filepath, api
# 循环结束后,保存表格


def Download_image(filepath, Path_Download, Path_IDM, api):
workbook_read = xlrd2.open_workbook(filepath)
# 打开表格,创建工作空间
sheet1 = workbook_read.sheet_by_name('Url_image')
# 选择需要读取的sheet
link_list = sheet1.col_values(0)
# 获取第一列的数据
print('所有链接下载完成,现在开始下载对应数据')
num = 0
while link_list:
print('---------------------------------------------------')
num += 1
print('\n')
print('第' + str(num) + '次循环' + '\n')
id = link_list[0].split('\'')[1]
link = link_list[0]
info_product = api.get_product_odata(id)
print('查询当前列表里的第一个数据的状态')
if info_product['Online']:
print(info_product['title'] + '为:online产品')
print('加入IDM的下载列表中: ')
print('\n')
call([Path_IDM, '/d', link, '/p', Path_Download, '/n', '/a'])
link_list.remove(link)
call([Path_IDM, '/s'])
else:
print(info_product['title'] + '为:offline产品')
print('\n')
print('激活offline产品')
code_id = link_list[0].split('\'')[1]
api.trigger_offline_retrieval(code_id)
# 激活offline产品
print('检查任务列表里是否存在online产品: .........')
# 等待激活成功的时候,检查现在的列表里还有没有online产品
# 如果有online的产品那就下载
# 首先检查列表中是否需要下载的数据
if len(link_list) > 1:
# 记录列表里可以下载的链接,并在最后把它们删除
link_list_1 = []
# 开始寻找列表剩下的元素是否有online产品
for i in range(1, len(link_list)):
id2 = link_list[i].split('\'')[1]
link_1 = link_list[i]
info_product2 = api.get_product_odata(id2)
if info_product2['Online']:
print(info_product2['title'] + '为Online产品')
print('加入IDM的下载列表中: ')
print('--------------------------------------------')
call([Path_IDM, '/d', link_1, '/p', Path_Download, '/n', '/a'])
# 在列表中加入需要删除产品的HTTP链接信息
# 直接在link_list中删除会link_list的长度会发生改变,最终造成i的值超过link_list的长度
link_list_1.append(link_1)
else:
continue
# 把已经下载的数据的链接给删除掉
if len(link_list_1) > 0:
call([Path_IDM, '/s'])
for link_2 in link_list_1:
link_list.remove(link_2)
print('本轮次检查结束,开始等到40分钟')
# 将该激活的产品删除,再加入到最后
link_list.remove(link)
link_list.append(link)
# 两次激活offline数据的间隔要大于30分钟
for i in tqdm(range(int(1200)), ncols=100):
time.sleep(2)


if __name__ == "__main__":
"""说明文档:https://sentinelsat.readthedocs.io/en/latest/api_overview.html,
https://scihub.copernicus.eu/userguide/AdvancedSearch"""
login = '**********'
key = '********'
path_geojson = "G:/map.geojson"
start_date = "20230101"
end_date = "20230301"
name = 'Sentinel-2'
product_type = 'S2MSI2A'
cloud = (0, 15)
filepath = 'G:/url.xls'
# 存储下载链接的表格
filepath, api = Search_data(login, key, path_geojson, start_date, end_date, name, product_type, cloud, filepath)
Download_Path = 'G:/try_download/'
# 数据要下载的地址,IDM的下载地址
Path_IDM = "D:/IDM/IDMan.exe"
Download_image(filepath, Download_Path, Path_IDM, api)

注意事项

执行到这一段代码call([Path_IDM, '/d', link, '/p', Path_Download, '/n', '/a']),有时候IDM会提示:保存的文件名称是$value…,需要确认才能继续下载。因而代码执行到这一步就会卡在这里,目前没有找到解决方式。

1.png

既然已经导出需要下载的excel文档了,整理下下载的url地址,直接批量添加到IDM里面下载即可。😁👻

url下载地址

2.png

导入IDM

3.png

还没有识别,显示$value

4.png

识别成功

5.png

参考文章

【Python&RS】基于Python批量下载哨兵二号数据_哨兵数据下载_RS迷途小书童的博客-CSDN博客