python下载哨兵一号轨道数据
最近因为项目需要,突然想起来自己曾写过这么一份脚本,就顺便修改了一下。首先明确一下我们的目标,根据已经下载的哨兵1号影像文件,下载哨兵1号对应的精密轨道数据。哨兵轨道数据下载网站目前用的多的有两个,分别是:
1.欧空局
2.美国earthdata
由于欧空局下载需要科学上网,因此我们这里选用earthdata网站。
可以看到这里的数据十分齐全,最近的更新日期20230322,最新的轨道日期是20230302的。
这里需要提醒一下,轨道文件的第一个日期为轨道数据更新日期,第二个和第三个日期的中间那一天才是影像的成像日期。
明确了下载目标,下面我们来研究一下这个网站。打开开发者模式,随机选择其中一条数据。
可以看到所有的文件都在pre标签下。任意选中一条数据复制其地址如下:https://s1qc.asf.alaska.edu/aux_poeorb/S1A_OPER_AUX_POEORB_OPOD_20140822T122852_V20140731T225944_20140802T005944.EOF
可以看出格式大体相似,接下来我们要做的就是根据我们自己的影像日期利用去寻找出这些链接地址,然后下载。下面来拆分一下任务:
1.下载轨道文件列表集合
2.根据自己的影像文件提取出需要下载的数据
3.下载数据。
1.获取文件列表
request = urllib.request.Request(url=url)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8') #获得源码
mw_list = re.findall(r'"[S1A_OPER_AUX_POEORB_OPOD_].*?[.EOF]">',content)
这里我们采用的方法是先获取该网站下的全部源码,接着使用正则表达式提取出文件列表,该正则表达式可以匹配所有以S1A_OPER_AUX_POEORB_OPOD_开头、以EOF中的任意一个字符结尾,并以">"字符结尾的子串。:
从图片上我们可以看出,已经成功的提取处理所有的轨道文件名称列表。
2.根据自己的影像提取出需要下载的数据文件
这里的思路是首先根据影像日期去遍历文件列表,利用正则表达式提取出对应的文件名称。
2.1提取影像日期
timelist = []
def get_file_list(dir):
for parent, dirnames, filenames in os.walk(dir):
for file in filenames:
result = re.search(r'[2]\d{7}',file)
timelist.append(result.group())
return timelist
这里利用的是os.walk函数,该函数可以分类返回文件和文件路径,这里就不详述了。根据返回的文件名称提取,对于给定的正则表达式’[2]\d{7}',含义如下:[2]:匹配数字2;\d{7}:匹配7个任意数字。因此,该正则表达式可以匹配所有以数字2开头,后跟7个任意数字的子串。
2.2匹配轨道文件名称
for i in mw_list:
a, filename, c = i.split('"')
result = re.search(r'S1A.*[V](\d{8})', filename)
dt = datetime.strptime(result.group(1), '%Y%m%d') # 将字符串转换成 datetime 对象
one_day = timedelta(days=1) # 创建一个时间差对象,表示一天
dt_plus_one_day = datetime.strptime(time, '%Y%m%d')
if dt_plus_one_day == dt + one_day: # 将原始日期加上一天
srcl = url + filename
根据轨道文件的第二个日期问影像成像日期的前一天这个特性,我们利用判断语句寻找出所有得文件。
3.下载数据
该网站得下载需要授权,也就是登录,采用得方法为GET方法。为了防止反爬,我这里使用了代理池和多个浏览器模拟。
3.1 为防止被禁需要使用代理池
这里我介绍一个免费的获取代理的网站,快代理:
只需要用该网站上的免费代理将下文的ip替换即可。
proxy_list = [
'117.91.254.237',
'123.169.124.72',
'122.143.213.135',
'112.109.221.50',
'36.56.101.237',
'110.242.130.113',
'113.194.136.201',
'125.72.106.161',
'20.86.39.237'
]
proxy = {'http': random.choice(proxy_list)}
3.3 模拟浏览器 定义请求头
header = [
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14",
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)",
'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
'Opera/9.25 (Windows NT 5.1; U; en)',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
"Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7",
"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 "
]
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'User_agent': random.choice(my_headers),
'Cookie': 登录asf网站打开检查即可查看,并复制粘贴到此处
}
3.4定义formdata,进行模拟登录
formdata = {
'redir': 'https://urs.earthdata.nasa.gov/oauth/authorize?response_type=code&client_id=BO_n7nTIlMljdvU6kRRB3g&redirect_uri=https://auth.asf.alaska.edu/login',
'form_email': username, #'asf网站的用户名'
'form_password': password, #密码
'login': u'登陆'
}
3.5获取轨道文件内容
s = requests.session()
response2 = s.get(url=srcl, proxies=proxy, data=formdata, headers=headers)
content = response2.text
3.6 写入文件
file = os.path.join(dir, filename)
with open(file, 'wb') as wstream:
wstream.write(response2.content)
通过逐步得分解,我们摸清了所有得操作流程。下面是完整的代码,有需要的童鞋可以看看,使用的时候清记得替换上自己用户名和密码,以及请求头。
# -*- coding:utf-8 -*-
import urllib.request
import urllib.parse
import re
import requests
import random
import os
url = 'https://s1qc.asf.alaska.edu/aux_poeorb/'
proxy_list = [
'182.34.17.104',
'121.13.252.58',
'116.9.163.205',
'61.216.185.88',
'117.114.149.66',
'183.236.232.160',
'117.41.38.16',
'210.5.10.87',
'121.13.252.60'
]
proxy = {'http': random.choice(proxy_list)}
#print(proxy)
my_headers = [
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36",
"Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0",
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.75.14 (KHTML, like Gecko) Version/7.0.3 Safari/537.75.14",
"Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0)",
'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11',
'Opera/9.25 (Windows NT 5.1; U; en)',
'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)',
'Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.5 (like Gecko) (Kubuntu)',
'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.0.12) Gecko/20070731 Ubuntu/dapper-security Firefox/1.5.0.12',
'Lynx/2.8.5rel.1 libwww-FM/2.14 SSL-MM/1.4.1 GNUTLS/1.2.9',
"Mozilla/5.0 (X11; Linux i686) AppleWebKit/535.7 (KHTML, like Gecko) Ubuntu/11.04 Chromium/16.0.912.77 Chrome/16.0.912.77 Safari/535.7",
"Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0) Gecko/20100101 Firefox/10.0 "
]
headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
'User_agent': random.choice(my_headers),
'Cookie':'_ga_XXXXXXXXXX=GS1.1.1648455850850.as3di3qk.1.1.1648455850.0; _gid=GA1.2.1768425303.1679376735; asf-urs=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmaXJzdF9uYW1lIjoibHVvIiwibGFzdF9uYW1lIjoicWlhbmciLCJ1cnMtdXNlci1pZCI6ImxsbHEiLCJ1cnMtYWNjZXNzLXRva2VuIjoiZXlKMGVYQWlPaUpLVjFRaUxDSnZjbWxuYVc0aU9pSkZZWEowYUdSaGRHRWdURzluYVc0aUxDSnphV2NpT2lKbFpHeHFkM1J3ZFdKclpYbGZiM0J6SWl3aVlXeG5Jam9pVWxNeU5UWWlmUS5leUowZVhCbElqb2lUMEYxZEdnaUxDSmpiR2xsYm5SZmFXUWlPaUpDVDE5dU4yNVVTV3hOYkdwa2RsVTJhMUpTUWpObklpd2laWGh3SWpveE5qZ3hPVFk1TURZeUxDSnBZWFFpT2pFMk56a3pOemN3TmpJc0ltbHpjeUk2SWtWaGNuUm9aR0YwWVNCTWIyZHBiaUlzSW5WcFpDSTZJbXhzYkhFaWZRLlNoZ1hzdHNvS04yT3JoR3dTcXJqSUN0Z0g2V2lORG1IV1FzNGdrQUVKaktVekc2VWVkQmRzbGt3bHAxNGVVRHB5dVpGZlJwUkJBeC01VUpmMk1lLUpRNG5xZGpsMmJ5MHd1STE0SXVJUjlJVENsbEkxLUxPNUxPZHgxTnBfd0VwcEJrSWQ2SkhMUmdfX1doTC0wVklycGhkNkNCWnBzVXEwR1JTYmJoUWZhQWhYQlBaMm5ZMnFnVnJvbzluWHkzandLbWRWR21CY1E0bVV6UkFvdXNRNTZidy1YYmN5UnhUVVFJQUszb0hLek5DQzh6bHh1Q1h4ZWcyNExnd0JiS1pEQ1NQT3NJRXdTa2NsNTBVOEtMOHNKMThya2JlUndSYTZHOVZZV0x1ZXZaZ3BBUzBMY0NEbGFtZXFXYU1ta3ZubldIWW9LeUxMcE0yOHBRNXlQWUo3ZyIsInVycy1ncm91cHMiOltdLCJpYXQiOjE2NzkzNzcwNjMsImV4cCI6MTY3OTk4MTg2M30.T694NhEly5cx5myAWdeqdq2KBxfKoYYGlVjdjnMrlt19z1DhmMXydbb5f6bUB3KL05R56_ifDF5ez3e7dJYaxkIs7uWOY4v5wQ3iVEmkG-m5YkfRJiDwrk_UGfwUvav5dIIud1a2MSnYAZudrKhCFc2WJVfNSJZLJdggAbCv3FPHetJ3bOs4rSltCzfeadG0LDoM9kkJ0z6ABfOblMj3dHee-MoujClrhkI225_dHUqM5jJhPr1JSAOsmEFsCg7Xph7Bti_RbYsRKeNGiWNMNauiKLRtNS5e-MQoXjvpCw9oPxMvlGrsyAP4D78rCspC65l4kgH9Nl_VF3S-HuCR-l1ndyRYdDVVyQz3H12TC0O0SxumaVg1QESRBPMBeJVzd4EVYmINK3s9k8rZgla2NNtYcPLYSCuFzIfvBqTv3ya46UfGwHsT-w2o0oMZnqjp9n0Q__OdONQ4nvxEb2hD3WEWQJ4Z_KDxW-spFlabZ_5l5ZtAHwgAYTN55OWzqwtdk6wD2PiRjlgqYRyTqb8EAPGMfLKXblHnzGis3Y-8ycAyALc4TqXtzahD-T2WWYqI8TtHndy4TbqPPaQ3mViKCIvzfnXlWoVuTRx6_m8fj112lqayFGhIGJmo5wg8IME5q9L3tKjE0Ue21k9kpzEBPcDXW02Y5FnKtH4BKDveeSI; urs-user-id=lllq; urs-access-token=eyJ0eXAiOiJKV1QiLCJvcmlnaW4iOiJFYXJ0aGRhdGEgTG9naW4iLCJzaWciOiJlZGxqd3RwdWJrZXlfb3BzIiwiYWxnIjoiUlMyNTYifQ.eyJ0eXBlIjoiT0F1dGgiLCJjbGllbnRfaWQiOiJCT19uN25USWxNbGpkdlU2a1JSQjNnIiwiZXhwIjoxNjgxOTY5MDYyLCJpYXQiOjE2NzkzNzcwNjIsImlzcyI6IkVhcnRoZGF0YSBMb2dpbiIsInVpZCI6ImxsbHEifQ.ShgXstsoKN2OrhGwSqrjICtgH6WiNDmHWQs4gkAEJjKUzG6UedBdslkwlp14eUDpyuZFfRpRBAx-5UJf2Me-JQ4nqdjl2by0wuI14IuIR9ITCllI1-LO5LOdx1Np_wEppBkId6JHLRg__WhL-0VIrphd6CBZpsUq0GRSbbhQfaAhXBPZ2nY2qgVroo9nXy3jwKmdVGmBcQ4mUzRAousQ56bw-XbcyRxTUQIAK3oHKzNCC8zlxuCXxeg24LgwBbKZDCSPOsIEwSkcl50U8KL8sJ18rkbeRwRa6G9VYWLuevZgpAS0LcCDlameqWaMmkvnnWHYoKyLLpM28pQ5yPYJ7g; _ce.s=v~1afe2267d9729a004013f47f95c41669aa19cccd~vpv~2~v11.rlc~1679446161225; _ga_N5CLEFBXPF=GS1.1.1679446124.3.1.1679446163.0.0.0; _ga_HGQJE87DVC=GS1.1.1679446163.1.0.1679446163.0.0.0; _ga=GA1.2.992160214.1648455100; _ga_XCPHL9DW7E=GS1.1.1679446124.3.1.1679446182.0.0.0'
}
formdata = {
'redir': 'https://urs.earthdata.nasa.gov/oauth/authorize?response_type=code&client_id=BO_n7nTIlMljdvU6kRRB3g&redirect_uri=https://auth.asf.alaska.edu/login',
'form_email': yourusename
'form_password': password,
'login': u'登陆'
}
#request = urllib.request.Request(url=url, headers=headers)
request = urllib.request.Request(url=url)
response = urllib.request.urlopen(request)
content = response.read().decode('utf-8') #获得源码
pattern = re.compile('"[S1A_OPER_AUX_POEORB_OPOD_].*?[.EOF]">', re.S)
mw_list = pattern.findall(content)
mw_list = re.findall(r'"[S1A_OPER_AUX_POEORB_OPOD_].*?[.EOF]">',content)
print(mw_list)
spath = r'D:\workspace\hubei' # 哨兵数据目录
dir = r'D:\workspace\hubei\orbit_file' # 下载数据目录
timelist = []
def get_file_list(dir):
for parent, dirnames, filenames in os.walk(dir):
for file in filenames:
result = re.search(r'[2]\d{7}',file)
timelist.append(result.group())
return timelist
# example srcl https://s1qc.asf.alaska.edu/aux_poeorb/S1A_OPER_AUX_POEORB_OPOD_20210330T233246_V20190706T225942_20190708T005942.EOF
# srcl https://s1qc.asf.alaska.edu/aux_poeorb/S1A_OPER_AUX_POEORB_OPOD_20210215T121728_V20210125T225942_20210127T005942.EOF
timelist = get_file_list(spath)
from datetime import datetime, timedelta
s = requests.session()
for time in timelist:
try:
for i in mw_list:
a, filename, c = i.split('"')
result = re.search(r'S1A.*[V](\d{8})', filename)
dt = datetime.strptime(result.group(1), '%Y%m%d') # 将字符串转换成 datetime 对象
one_day = timedelta(days=1) # 创建一个时间差对象,表示一天
dt_plus_one_day = datetime.strptime(time, '%Y%m%d')
if dt_plus_one_day == dt + one_day: # 将原始日期加上一天
srcl = url + filename
response2 = s.get(url=srcl, proxies=proxy, data=formdata, headers=headers)
content = response2.text
file = os.path.join(dir, filename)
with open(file, 'wb') as wstream:
wstream.write(response2.content)
print('{}已下载完成!'.format(filename))
break
except:
print('未找到{}号文件,下载失败'.format(time))
continue
print('下载完成!')