提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
最近在处理sar数据,下载大量哨兵数据后发现还要下载对应的轨道数据,而一个一个点又比较繁琐(不是懒) ,因此在参考大佬 @WhyLearnCode 基础上进行改进,本代码适合统计好下载影像的时间序列后针对性的对所需轨道数据进行下载。
参考大佬博客链接:https://blog.csdn.net/WhyLearnCode/article/details/123391537
第一次写文章,略有不足还请见谅!
一、轨道数据
哨兵轨道数据下载网站目前用的多的有两个,分别是:
但是我用的时候第一个进不去,可能要挂梯子?遂用第二个网站
二、准备工作
1.统计下载哨兵影像的时序
新建Excel文件,格式xlsx,xls,xlsm都可以,并将其命名为datetable(这里有一点要注意:在python安装读取excel文件的xlrd库时需要安装老版本1.2.0,因为新版本读取格式比较受限)
统计示例如下图,建议首行就是数据值,不然就自行在代码的read_excel函数中微调。
改动代码位置如下:
for i in range(0, nrows): #第0行为表头,如果首行为其他信息就改为1
data = sheets.row_values(i)
for j in range(len(data)):
data[j] = re.sub('[-,., ]','',data[j])
2.拿到下载网站的Cookie
参考博客以Google游览器为例,很详述,这里以游览器Edge为例:
-
打开下载网页右键,最底下一项为检查(或按F12)进入浏览器开发者模式
-
右边最上面一栏找到网络按钮,点击进入,并按下ctrl+r:
-
在名称一栏点击文件,就可以看到网站信息,点击标头就可以看到我们所需要的Cookie信息,新建cookie.txt后复制信息将其存放,并将cookie.txt移动到轨道数据存放文件夹下。
这里要注意,如果电脑版本不是win10,可能要根据标头(Header)对download函数里的headers列表进行微调。
3.创建虚拟环境并安装所需库
本人使用Anaconda创建虚拟环境,具体可参考博客:https://blog.csdn.net/wq_ocean_/article/details/103889237 很详细
创建好虚拟环境后,在命令提示符中键入(conda activate -环境名 )激活虚拟环境,并进行库的安装,以下为所需库:(键入时后面的备注就不要打了)
pip install bs4 #从 HTML 或 XML 文档中快速地提取指定的数据
pip install requests #Python实现的简单易⽤的HTTP库
pip install parse #解析URL
pip install python-dateutil #时间处理模块
pip install xlrd==1.2.0 #读取excel
安装所需库后在PyCharm中创建工程激活环境,具体流程参考博客:https://blog.csdn.net/weixin_38858443/article/details/108966449
三、导入代码
1.代码修改部分
此处和参考博客类似,大致为
1.out_path = r'G:\精轨数据' #存放轨道数据文件夹位置
2.cookie_path = r'G:\精轨数据\cookie.txt' #在上步文件夹下cookie文件位置
当然也可以不提前输入文件夹路径,自己进行选择,那么就将上面的代码注释掉,换成
1. out_path=filedialog.askdirectory() #选择文件夹
2. cookie_path=filedialog.askopenfilename() #直接选择cookie文件
2.代码思路
将哨兵数据下载时间(也就是所需要轨道数据的时间)存放在NeedTimeArray数组里,再通过对网站上EOF数据进行筛选,若数据日期(轨道数据之间有两个日期)正好将哨兵数据时间“夹”住,那么就对其执行下载操作,反之则跳出循环进行下一个数据的筛选。
3.代码如下(下载所需轨道数据):
from urllib.parse import urlparse
import urllib.request
from bs4 import BeautifulSoup
import re
import os
import datetime
from dateutil.parser import parse
import requests
import xlrd #注意 xlrd1.2.0版本支持对旧版excel格式的读取,默认pip为新版2.0.1
import tkinter as tk
from tkinter import filedialog
""" Notice
本代码爬取轨道数据来自于网站:https://s1qc.asf.alaska.edu/aux_poeorb/
代码需要更改地方有:
1.存放轨道数据文件夹位置
2.在上步文件夹下新建cookie.txt,存取网址的cookie信息
注意:download下的headers数组里存放的实际上轨道数据的网站信息,这个根据电脑版本(win10,win11)或平台(window,OS)要进行小调
"""
timestart = datetime.datetime.now()
def download(dest_dir, url,cookie_path):
print(url)
print(dest_dir)
cookie = str(open(cookie_path,"r").read())
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",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh-CN,zh;q=0.9",
"Connection": "keep-alive",
"Cookie" : cookie,
"Host": "s1qc.asf.alaska.edu",
"Referer": "https://s1qc.asf.alaska.edu/aux_poeorb/?sentinel1__mission=S1A&validity_start=2015-02-19",
"sec-ch-ua": "\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"96\", \"Google Chrome\";v=\"96\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows \"",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": "?1",
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
}
try:
request = urllib.request.Request(url,headers=headers)
response = urllib.request.urlopen(request)
f = open(dest_dir ,"w")
lines = response.readlines()
for line in lines:
f.write(line.decode())
f.close()
except:
error_url.append(url)
print("\tError retrieving the URL:", dest_dir)
else: # 没有异常
if url in error_url: #在错误列表里
error_url.remove(url)
def read_excel(dir_path):
try:
NeedTimeArray = []
dir_list = os.listdir(dir_path) # dir_path :文件夹路径
for dir in dir_list: #搜寻文件夹
#搜寻excel文件并读取存储到NeedTimeArray
if os.path.splitext(dir)[1] == ".xlsx" or os.path.splitext(dir)[1] == ".xls" or os.path.splitext(dir)[1] == ".xlsm" : #后缀为excel表格格式
excel_path = os.path.join(dir_path, dir)
work_book= xlrd.open_workbook(excel_path) #注意
sheets = work_book.sheets()[0] #选定表
nrows = sheets.nrows#获取行号
ncols = sheets.ncols#获取列号
for i in range(0, nrows):#第0行为表头,第一行为数据就改为0
data = sheets.row_values(i)#循环输出excel表中每一行,即所有数据
for j in range(len(data)): #将excel格式(如2015.06.22,2015-06-22)变成需要的8数字格式
data[j] = re.sub('[-,., ]','',data[j])
NeedTimeArray.append(data)
return NeedTimeArray
except BaseException as e: #抛出异常的处理
print(str(e))
if __name__ == '__main__':
#创建调用文件夹所需对象
root=tk.Tk()
root.withdraw()
error_url = [] #存放下载出错的文件名
cookie_path = r'G:\精轨数据\cookie.txt' #cookie文件位置
out_path = r'G:\精轨数据' #轨道文件输出位置
# out_path=filedialog.askdirectory() #选择文件夹
# cookie_path=filedialog.askopenfilename() #直接选择cookie文件
url_param_json = {}
url_param_json['sentinel1__mission'] = 'S1A'
date = '2015-01-01' #开始搜寻日期
url_param_json['validity_start'] = date
# 获得EOF下载网址
url_param = urllib.parse.urlencode(url_param_json) #url参数
url = 'https://s1qc.asf.alaska.edu/aux_poeorb/?%s' % url_param #拼接
html=requests.get(url).content
dom = BeautifulSoup(html,"lxml") # 解析html文档
a_list = dom.findAll("a") # 找出<a>
eof_lists = [a['href'] for a in a_list if a['href'].endswith('.EOF')] # 找出EOF
TimeArray=[] # 存放网站爬取EOF文件的时间信息
NeedTimeArray = read_excel(out_path) # 存放下载数据的时间信息
for eof in eof_lists:
#截取轨道文件的时间信息
if os.path.splitext(eof)[1] == ".EOF" and os.path.basename(eof)[0:3] == 'S1A': # 后缀是eof且前缀前三个字符为S1A
SplitEOF = re.split(r'[_,.,\s ]\s*', eof) #将EOF文件分割
SplitTime = SplitEOF[-2] #分割列表中取表中最后一个日期
Time = parse(SplitTime) #转换成时间格式
NeedTime = Time+datetime.timedelta(days=-1) # 转换成所需时间
NeedTimeNum =(re.sub('[-,:, ]','',str(NeedTime)))[0:8] #将时间格式转换成需要的数字格式,sub为去除字符串中符号
if NeedTimeNum in str(NeedTimeArray ):
TimeArray.append(NeedTimeNum) # 存放准备下载的时间
savefile = os.path.join(out_path,eof)
download(savefile,'https://s1qc.asf.alaska.edu/aux_poeorb/'+eof,cookie_path)
print ("------------------------------------")
print("精密轨道数据下载完成")
print("------------------------------------")
if len(TimeArray) == len(NeedTimeArray):
print("所需精密轨道数据下载完成,共计%d个文件" %(len(TimeArray)))
print("------------------------------------")
break
else :
continue
# 下载出错的数据重新下载
while len(error_url)!=0:
print ("开始下载出错的数据")
print("------------------------------------")
print("出错的数据有")
print(error_url)
for eof in error_url:
savefile = os.path.join(out_path, eof[50:])
download(savefile, eof,cookie_path)
timeend = datetime.datetime.now()
print('Running time: %s Seconds'%(timeend-timestart))
总结
网络爬取速度有限,可能和网速有关,有时一两分钟一个EOF文件,有时一分钟几个EOF文件,建议晚上挂着第二天就下好了,省时省力,爬取时有个问题是在从17年开始的数据爬下来两份,如20170313的数据,一份是2021年3月1日发布,一份是2017年4月1日发布,不知道是否有改动的地方,因为下载策略是根据日期来进行判断,因此后续如果有能力的同学可以在此基础上进行改进。
跑的不快,但总算是没出错,实测可行。