写在前面
好久没更新了,不是忘了,是懒!
正好最近想下载哨兵1号数据来反演一下地表形变,于是乎,就撰写此文记录一下坎坷的路程。
反演地表形变,首先得有哨兵数据,于是在 Open Access Hub (copernicus.eu) 网站上搜寻了一番,选了一些数据(此处略去)。
选的数据很多,要是一个一个点击下载,实在太过于麻烦,直觉告诉我肯定有自动批量下载的方式,于是bing了一下,果然有。
大概浏览了一下,无非就那么几种,要么是通过 https://search.asf.alaska.edu/ 这个网站上自动生成的python代码,要么就是结合 IDM 下载器,通过编写python代码下载。
第一种看起来最简单,尝试了一下,的确可以自动生成Python代码,大概长这样:
不用自己写,很方便,要下载的数据链接也可以从生成的代码上直观看到。
但是!!!最怕的但是还是来了!我尝试了很多次,都没法下载,报一个类似下面的错误:
又bing了半小时,无果。
连接不上,看来得翻墙了。果然,一翻墙,数据就开始下载了。
翻墙终归不是一个好的办法,流量有限。于是,中途抱着侥幸心理,把VPN关了,妄想还能继续下载。果然是妄想,分分钟给你断开连接!
无奈只得转向另一种下载方式了,很巧不小心看到这几篇文章https://www.tqwba.com/x_d/jishu/295307.html
【Sentinel】1. 批量下载offline数据_冰柚子的博客-优快云博客_哨兵数据offline
按照文章上的操作,略微修改了下代码,就成功了!不用翻墙也可以顺利下载,不过前提是得安装IDM下载器。这个下载器还是挺好用的,以前只用它爬过视频,现在似乎什么都能下载,从学术论文到娱乐视频,都可以加速下载,针不戳!
要点
话不多说,贴一下下载要点,记录一下,主要代码都是上述文章里COPY过来!详细过程可以参考上述文章。
1、用Microsoft Edge浏览器,使用快捷键为ctrl+s,将网页保存下来
2、用以下代码,把网页里的文件名和下载链接存到xlsx里
#!/usr/bin/python
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
import pandas as pd
import requests
filepath='scihub.copernicus.eu.html' #保存的网页,自己按照实际保存位置调整
with open(filepath,'rb') as f:
ss=f.read()
soup=BeautifulSoup(ss,'html.parser')
###-------可选:获取 购物车中的数据链接------###
#获取所有id为cart-row-attributes的div标签
divfind=soup.find_all('div',id='cart-row-attributes')
###-------可选:获取 检索页面的数据链接------###
#获取所有class为'list-link selectable'的div标签
# divfind=soup.find_all('div',class_='list-link selectable')
linklist=[]
idlist=[]
for df in divfind:
#获取满足条件的div下的a标签
#提取a标签的内容,即为数据链接
link=df.find('a').string
id=link.split('\'')[1]
linklist.append(link)
idlist.append(id)
linkdataframe=pd.DataFrame(linklist)
iddataframe=pd.DataFrame(idlist)
#将数据链接写出
with pd.ExcelWriter('Httpandid.xlsx') as hifile:
linkdataframe.to_excel(hifile,sheet_name='HTTP',header=False,index=False)
iddataframe.to_excel(hifile,sheet_name='ID',header=False,index=False)
3、使用以下代码(需要提前 pip install sentinelsat,python环境最好是3.6以上,2.7貌似报错了),结合IDM下载器,把xlsx存储的数据下载下来。IDM下载还需要简单的设置一下,就懒得截图了,参考上述文章吧!
#!/usr/bin/python
# -*- coding: utf-8 -*-
from subprocess import call
from sentinelsat import SentinelAPI
from datetime import date
import time
import xlrd
from tqdm import tqdm
IDM = "E:\Program Files\Internet Download Manager\IDMan.exe" #你电脑中IDM的位置
DownPath='Sentinel_offline/' #数据要下载的地址
api = SentinelAPI('username', 'password', 'https://scihub.copernicus.eu/dhus') #填写用户名和密码
#用于读取数据的HTTP链接到列表中
filepath='Httpandid.xlsx'
workbook = xlrd.open_workbook(filepath)
sheet1 = workbook.sheet_by_name('HTTP')
linklist=sheet1.col_values(0)
#开始下载
print('开始任务:..................')
n=0
while linklist:
print('---------------------------------------------------')
n=n+1
print('\n')
print('第'+str(n)+'次循环'+'\n\n')
id=linklist[0].split('\'')[1]
link=linklist[0]
product_info=api.get_product_odata(id)
print('检查当列表里的第一个数据:')
print('数据ID为:'+id)
print('数据文件名为:'+product_info['title']+'\n')
if product_info['Online']:
print(product_info['title']+'为:online产品')
print('加入IDM下载: '+link)
call([IDM, '/d',link, '/p',DownPath,'/n','/a'])
linklist.remove(link)
call([IDM,'/s'])
else:
print(product_info['title']+'为:offline产品')
print('去激活它')
api.download(id) #去激活它
print('检查任务列表里是否存在online产品: .........')
#等待激活成功的时候,检查现在的列表里还有没有online产品
#如果有online的产品那就下载
#首先检查列表中是否需要下载的数据
if len(linklist)>1:
#记录列表里可以下载的链接,并在最后把它们删除
ilist=[]
#开始寻找列表剩下的元素是否有online产品
for i in range(1,len(linklist)):
id2=linklist[i].split('\'')[1]
link2=linklist[i]
product_info2=api.get_product_odata(id2)
if product_info2['Online']:
print(product_info2['title']+'为在线产品')
print('ID号为:'+id2)
print('加入IDM下载: '+link2)
print('--------------------------------------------')
call([IDM, '/d',link2, '/p',DownPath,'/n','/a'])
#在列表中加入需要删除产品的HTTP链接信息
#直接在linklist中删除会linklist的长度会发生改变,最终造成i的值超过linklist的长度
ilist.append(link2)
else:
continue
#把已经下载的数据的链接给删除掉
if len(ilist)>0:
call([IDM,'/s'])
for il in ilist:
linklist.remove(il)
print('本轮次检查结束,开始等到40分钟')
#将该激活的产品删除,再加入到最后
linklist.remove(link)
linklist.append(link)
#两次激活offline数据的间隔要大于30分钟
for i in tqdm(range(int(1200)),ncols=100):
time.sleep(2)
可能出现的问题
1、使用不同的浏览器,网页里面的内容可能会有差别,可能需要做相应的修改,需要注意;
2、如果下载的offline数据过多的话,可能要不断进行激活,貌似一个账户一次能够激活的offline数据有限(20个?),超过这个数,可能会报错!
3、不激活offline数据,直接下载在线数据的话,就在把代码中 else 后面的内容注释掉,增加一句 linklist.remove(link) 把offline数据给移掉就行了。
4、其他问题,暂时没发现!