使用Python自动下载Himawari-8(葵花8)数据产品——以AOD L3级日均数据和小时数据为例

一:数据源介绍

葵花8号卫星是日本的一颗静止轨道气象卫星,覆盖范围为60S-60N, 80E-160W,除了提供十分钟一幅的原始卫星影像外,还提供了如气溶胶光学厚度(AOT,也叫AOD)、叶绿素A、海表温度、云层厚度以及火点等多种产品,这些数据都可以进行下载,本篇文章介绍的是使用python对AOD数据进行自动下载的代码。

二:账号注册

首先需要在“https://www.eorc.jaxa.jp/ptree/”网站进行注册,打开该网站后,在右上角选择“User Registration”,根据提示完成注册。

注册成功后,会收到一封包含用户名(UID)和密码(PW)的邮件,若使用浏览器手动下载可以直接打开ftp后的地址(邮件说的很清楚,看不懂可以谷歌翻译)

打开高亮部分的网址后,可以看到jma文件夹、pub文件夹和两个文本文件,其中,jma文件夹和pub文件夹中存放的都是向日葵系列卫星的影像产品,文本文件的内容是每种影像产品的存放位置和数据介绍。

本代码介绍的AOD数据位于“/pub/himawari/L3/ARP/030/yyyymm/dd/”文件目录下的AOD小时数据和位于“/pub/himawari/L3/ARP/030/yyyymm/daily/”目录下的AOD日均值数据,其中yyyy表示四位数年份,mm表示两位数月份,dd表示两位数天,大家可以根据自己的需要进行修改,也可以参考官方txt数据介绍文档寻找自己需要的数据的存储路径。

三:代码示例

废话不多说,直接上代码;

代码中都有注释,欢迎大佬批评指正;

最后说一句,科学上网不能提高下载速度,那样子可能网站进不去、连接不成功,还是慢慢等待吧...

如果追求速度,就搞一个日本服务器,网速够的话下载88MB的日数据也就几秒,再回传回自己的主机就可以了

# -*- codeing = utf-8 -*-
# -*- coding: GBK -*-
# @Time : 2020/8/19 10:32
# @Author : Cunese_Sen
# @File : Download_AOD.py
# @Software : PyCharm
# 可以部署在日本的服务器上,下载速度很快

import os
import ftplib
import time

dt = time.localtime(time.time())

_yearNum = dt.tm_year
_monNum = dt.tm_mon
_dayNum = dt.tm_mday
_yearStr = ""
_monStr = ""
_dayStr = ""


# 这个函数用于将日期从整型转为FTP路径所需的字符串
def getDateStr(yearNum, monNum, dayNum):
    # 四位数年份
    yearStr = str(yearNum)

    # 两位数月份
    if monNum < 10:
        monStr = "0" + str(monNum)
    else:
        monStr = str(monNum)

    # 两位数天
    if dayNum < 10:
        dayStr = "0" + str(dayNum)
    else:
        dayStr = str(dayNum)

    return yearStr, monStr, dayStr


# 这个函数用于在跨月时获取前一天的日期号
def getYesterday(year, month, day):
    if day == 1:

        if month == 1:
            year -= 1
            month = 12
            day = 31

        elif month == 2 or month == 4 or month == 6 or month == 8 or month == 9 or month == 11:
            month -= 1
            day = 31

        elif month == 5 or month == 7 or month == 10 or month == 12:
            month -= 1
            day = 30

        elif month == 3:
            # 闰年
            if year % 4 == 0 and year % 400 == 0:
                day = 29
                month -= 1
            # 闰年
            elif year % 4 == 0 and year % 100 != 0:
                day = 29
                month -= 1
            else:
                day = 28
                month -= 1
    else:
        day -= 1

    return year, month, day


# 获取文件后缀名
def suffix(file, *suffixName):
    array = map(file.endswith, suffixName)
    if True in array:
        return True
    else:
        return False


# 删除目录下扩展名为.temp的文件
def deleteFile(fileDir):
    targetDir = fileDir
    for file in os.listdir(targetDir):
        targetFile = os.path.join(targetDir, file)
        if suffix(file, '.temp'):
            os.remove(targetFile)


class myFTP:
    ftp = ftplib.FTP()

    # 连接FTP,host是IP地址,port是端口,默认21
    def __init__(self, host, port=21):
        self.ftp.connect(host, port)

    # 登录FTP连接,user是用户名,password是密码
    def Login(self, user, password):
        self.ftp.login(user, password)
        print(self.ftp.welcome)  # 显示登录信息

    # 下载单个文件,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, choice):
        # print("remoteDir:", 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")
            LocalNew = os.path.join(LocalDir, file)

            '''
            下载小时文件,只下载UTC时间1时至9时(北京时间9时至17时)的文件
            下载的文件必须是nc格式
            若已经存在,则跳过下载
            '''
            # 小时数据命名格式示例:H08_20200819_0700_1HARP030_FLDK.02401_02401.nc
            if choice == 1:
                if int(file[13:15]) >= 1 and int(file[13:15]) <= 9:
                    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)
                    elif os.path.exists(LocalNew):
                        print("The file of %s has already existed!\n" % file)
                else:
                    pass

            # 天数据命名格式示例:H08_20200802_0000_1DARP030_FLDK.02401_02401.nc
            elif choice == 2:
                if int(file[10:12]) == _dayNum and 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)
                elif int(file[10:12]) == _dayNum and os.path.exists(LocalNew):
                    print("The file of %s has already existed!" % file)

        self.ftp.cwd("..")
        return

    def close(self):
        self.ftp.quit()


if __name__ == "__main__":
    # 传入IP地址
    ftp = myFTP('ftp.ptree.jaxa.jp')

    # 传入用户名和密码
    ftp.Login('这里是您的帐号(UID)', '这里是您的密码(PW)')

    # 从目标路径ftp_filePath将文件下载至本地路径dst_filePath
    dst_filePath = input("请输入要存储下载的文件的本地路径:")  # E:/AOD_Download
    deleteFile(dst_filePath)  # 先删除存储路径中的临时文件(也就是上次未下载完整的文件)

    '''
    下载小时数据和日数据时,前置路径都是:/pub/himawari/L3/ARP/030
    下载日数据时,示例路径:/pub/himawari/L3/ARP/030/202008/daily/
    下载小时数据时,示例路径:/pub/himawari/L3/ARP/030/202008/19/
    '''
    print("请选择要下载的数据:")
    _choice = int(input("1.AOD小时数据(当天9:00至17:00)  2.AOD日均数据(昨天)\n"))

    if _choice == 1:
        _yearStr, _monStr, _dayStr = getDateStr(_yearNum, _monNum, _dayNum)
        ftp_filePath = "/pub/himawari/L3/ARP/030" + "/" + _yearStr + _monStr + "/" + _dayStr + "/"
        ftp.DownLoadFileTree(dst_filePath, ftp_filePath, _choice)
    elif _choice == 2:
        _yearNum, _monNum, _dayNum = getYesterday(_yearNum, _monNum, _dayNum)
        _yearStr, _monStr, _dayStr = getDateStr(_yearNum, _monNum, _dayNum)
        ftp_filePath = "/pub/himawari/L3/ARP/030" + "/" + _yearStr + _monStr + "/" + "daily" + "/"
        ftp.DownLoadFileTree(dst_filePath, ftp_filePath, _choice)
    else:
        print("选择错误!")

    # 结束
    ftp.close()
    print("下载完成!")

 

相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页