Python實現葵花8號衛星資料自動下載
本文已參與「新人創作禮」活動,一起開啟掘金創作之路。
Python實現葵花8號衛星資料自動下載
一:資料來源介紹
本篇文章介紹的是使用python實現對葵花8號衛星資料進行自動下載。
葵花8號衛星是日本的一顆靜止軌道氣象衛星,覆蓋範圍為60S-60N, 80E-160W,除了提供十分鐘一幅的原始衛星影像外,還提供瞭如氣溶膠光學厚度(AOT,也叫AOD)、葉綠素A、海表溫度、雲層厚度以及火點等多種產品,這些資料都可以進行下載。
二:FTP伺服器描述
首先需要在葵花8官網申請帳號。
可以通過FTP(ftp.ptree.jaxa.jp)使用申請的帳號密碼訪問檔案伺服器,可以看到jma資料夾、pub資料夾和兩個文字檔案,其中,jma資料夾和pub資料夾中存放的都是葵花系列衛星的影像產品,文字檔案的內容是每種影像產品的存放位置和資料介紹。
三: 程式描述
- 本程式碼下載Ftp伺服器如下地址下的檔案,如需使用可根據自己的需要進行修改,也可以參考官方txt資料介紹文件尋找自己需要的資料的儲存路徑。
- 使用/031目錄是因為資料最全。
/pub/himawari/L3/ARP/031/
- 本程式有兩個全域性除錯變數。
| 全域性變數 | True | False | 配置變數 | | ------------------ | ------------ | ---------- | --------------- | | debugLocalDownload | 下載到本地目錄 | 下載到伺服器指定目錄 | self._save_path | | debugDownloadDaily | 下載當前日期前1天的檔案 | 下載指定時間段的檔案 | - |
-
本程式有兩個版本在debugDownloadDaily=False時略有區別
- HimawariDownloadBulitIn的時間變數寫在程式內部,執行前需手動修改,適用於超算節點。
- HimawariDownloadCmdLine的時間變數通過命令列輸入,適用於登陸節點。
四:注意事項
- 程式碼無法直接執行 需要將以下行中的帳號和密碼替換成你申請的賬號密碼
五:程式碼
```
-- codeing = utf-8 --
可以部署在日本的伺服器上,下載速度很快
import ftplib import json import os import time import numpy as np
debugLocalDownload = True debugDownloadDaily = False
globPersonalTime = [2022, 9, 7]
class NumpyEncoder(json.JSONEncoder): def default(self, obj): if isinstance(obj, (np.int_, np.intc, np.intp, np.int8, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32, np.uint64)): return int(obj) elif isinstance(obj, (np.float_, np.float16, np.float32, np.float64)): return float(obj) elif isinstance(obj, (np.ndarray,)): return obj.tolist() return json.JSONEncoder.default(self, obj)
class himawari: ftp = ftplib.FTP()
def __init__(self):
self._url = '/pub/himawari/L3/ARP/031/'
self._save_path = './Your_save_path'
if debugLocalDownload:
self._save_path = './Download/'
self.ftp.connect('ftp.ptree.jaxa.jp', 21)
self.ftp.login('YourFTPAccount', 'YourFTPPassWord')
self._yearNum, self._monNum, self._dayNum = self.dayInit()
self._nginx_path = ''
print(self.ftp.welcome) # 顯示登入資訊
def run(self):
self._nginx_path = ''
try:
if debugDownloadDaily:
self._yearNum, self._monNum, self._dayNum = self.getYesterday(self._yearNum, self._monNum, self._dayNum)
else:
self._yearNum = globPersonalTime[0]
self._monNum = globPersonalTime[1]
self._dayNum = globPersonalTime[2]
self._yearStr, self._monStr, self._dayStr = self.getDateStr(self._yearNum, self._monNum, self._dayNum)
ftp_filePath = self._url + self._yearStr + self._monStr + "/" + self._dayStr + "/"
# 從目標路徑ftp_filePath將檔案下載至本地路徑dst_filePath
dst_filePath = self._nginx_path + self._save_path + self._yearStr + "/" + self._monStr + "/" + self._dayStr + "/" + "hour" + "/"
self.deleteFile(dst_filePath) # 先刪除未下載完成的臨時檔案
print("Local:" + dst_filePath)
print("Remote:" + ftp_filePath)
self.DownLoadFileTree(dst_filePath, ftp_filePath)
if debugDownloadDaily:
self.ftp.quit()
except Exception as err:
print(err)
def getYesterday(self, yy, mm, dd):
dt = (yy, mm, dd, 9, 0, 0, 0, 0, 0)
dt = time.mktime(dt) - 86400
yesterdayList = time.strftime("%Y-%m-%d", time.localtime(dt)).split('-')
return int(yesterdayList[0]), int(yesterdayList[1]), int(yesterdayList[2])
def dayInit(self, ):
yesterdayList = time.strftime("%Y-%m-%d", time.localtime(time.time())).split('-')
return int(yesterdayList[0]), int(yesterdayList[1]), int(yesterdayList[2])
def getDateStr(self, yy, mm, dd):
syy = str(yy)
smm = str(mm)
sdd = str(dd)
if mm < 10:
smm = '0' + smm
if dd < 10:
sdd = '0' + sdd
return syy, smm, sdd
# 刪除目錄下副檔名為.temp的檔案
def deleteFile(self, fileDir):
if os.path.isdir(fileDir):
targetDir = fileDir
for file in os.listdir(targetDir):
targetFile = os.path.join(targetDir, file)
if targetFile.endswith('.temp'):
os.remove(targetFile)
# 下載單個檔案,LocalFile表示本地儲存路徑和檔名,RemoteFile是FTP路徑和檔名
def DownLoadFile(self, LocalFile, RemoteFile):
bufSize = 102400
file_handler = open(LocalFile, 'wb')
print(file_handler)
# 接收伺服器上檔案並寫入本地檔案
self.ftp.retrbinary('RETR ' + RemoteFile, file_handler.write, bufSize)
self.ftp.set_debuglevel(0)
file_handler.close()
return True
# 下載整個目錄下的檔案,LocalDir表示本地儲存路徑, emoteDir表示FTP路徑
def DownLoadFileTree(self, LocalDir, RemoteDir):
# 如果本地不存在該路徑,則建立
if not os.path.exists(LocalDir):
os.makedirs(LocalDir)
# 獲取FTP路徑下的全部檔名,以列表儲存
self.ftp.cwd(RemoteDir)
RemoteNames = self.ftp.nlst()
RemoteNames.reverse()
# print("RemoteNames:", RemoteNames)
for file in RemoteNames:
# 先下載為臨時檔案Local,下載完成後再改名為nc4格式的檔案
# 這是為了防止上一次下載中斷後,最後一個下載的檔案未下載完整,而再開始下載時,程式會識別為已經下載完成
Local = os.path.join(LocalDir, file[0:-3] + ".temp")
files = file[0:-3] + ".nc"
LocalNew = os.path.join(LocalDir, files)
'''
下載小時檔案,只下載UTC時間0時至24時(北京時間0時至24時)的檔案
下載的檔案必須是nc格式
若已經存在,則跳過下載
'''
# 小時資料命名格式示例:H08_20200819_0700_1HARP030_FLDK.02401_02401.nc
if int(file[13:15]) >= 0 and int(file[13:15]) <= 24:
if not os.path.exists(LocalNew):
#print("Downloading the file of %s" % file)
self.DownLoadFile(Local, file)
os.rename(Local, LocalNew)
print("The download of the file of %s has finished\n" % file)
#print("png of the file of %s has finished\n" % png_name)
elif os.path.exists(LocalNew):
print("The file of %s has already existed!\n" % file)
self.ftp.cwd("..")
return
主程式
myftp = himawari() if debugDownloadDaily: myftp.run() else: yyStart, mmStart, ddStart = input("Start(yy mm dd):").split() yyStart, mmStart, ddStart = int(yyStart), int(mmStart), int(ddStart) yyEnd, mmEnd, ddEnd = input("End(yy mm dd):").split() yyEnd, mmEnd, ddEnd = int(yyEnd), int(mmEnd), int(ddEnd) dtStart = (yyStart, mmStart, ddStart, 9, 0, 0, 0, 0, 0) dtEnd = (yyEnd, mmEnd, ddEnd, 10, 0, 0, 0, 0, 0) timeIndex = time.mktime(dtStart) timeIndexEnd = time.mktime(dtEnd) while timeIndex < timeIndexEnd: indexDayList = time.strftime("%Y-%m-%d", time.localtime(timeIndex)).split('-') globPersonalTime[0] = int(indexDayList[0]) globPersonalTime[1] = int(indexDayList[1]) globPersonalTime[2] = int(indexDayList[2]) print(globPersonalTime) myftp.run() timeIndex = int(timeIndex) + 3600 * 24 ```