使用Python自动化、批量化的下载LAADS上的数据

目录

  1. 前言
  2. 剖析数据下载链接
  3. Python+Selenium+ChromeDriver配置
  4. 使用Python+Selenium调用wget下载数据
  5. 使用Python+Selenium调用IDM下载数据
  6. 总结

1.前言

LAADS(https://ladsweb.modaps.eosdis.nasa.gov/)是NASA的一个数据分发网站。在该网站上,可以下载很多卫星产品数据,如MODIS、VIIRS、Sentinel-3数据。

在LAADS下载数据,我们总是要经过如下几个步骤:选择传感器(还可以选产品版本)—>选择时间—>选择范围---->搜索文件—>提交订单。

前4个步骤在不需要登录账户的情况下就可以进行,而最后一个步骤就必须登录账户了(之前不需要登录账户,在进行到第四步即可点击下载检索到的文件)。

NASA官方提供给了大家很多使用脚本进行数据下载的方法,见:https://ladsweb.modaps.eosdis.nasa.gov/tools-and-services/data-download-scripts/

我们这里根据NASA的说明文档,根据需要写脚本,实现数据下载的简化。

如果研究区域和要用的数据产品是确定的,只是获取不同时间的数据。那么随着时间的变化,会有新的数据产生,我们就要手动重复数据下载步骤。

为了下载数据,我们最主要的任务是获取数据的下载链接。曾几何时在LAADS上下载数据是不需要登录账户的,而现在开始需要用户登录。因此,仅仅获取到下载链接是不够的,还要在链接中添加用户的验证信息。根据不同的下载工具,添加验证信息的方法也不同。这里本人分步骤进行介绍如何使用Python自动化、批量化的下载LAADS上的数据。

当然了,在下载数据之前,你应该有一个账号。

2.剖析数据下载链接

这里以下载MODIS的MOD021KM数据为例进行介绍。

当我们下载数据时,在进行到第四步时,就已经检索出来需要的文件,在用户登录的情况下,可以直接点击下载箭头进行单个文件下载。
使用Python自动化、批量化的下载LAADS上的数据_第1张图片
右键单击下载箭头,我们将一个文件的下载链接复制出来:

https://ladsweb.modaps.eosdis.nasa.gov/archive/allData/61/MOD021KM/2019/336/MOD021KM.A2019336.0200.061.2019336180824.hdf

然后点击页面中的"csv",会下载到一个csv文件。我们打开该文件:
使用Python自动化、批量化的下载LAADS上的数据_第2张图片
我们可以看到在下载的CSV文件中的第二列,只要在前边加上
‘https://ladsweb.modaps.eosdis.nasa.gov’ 就可以构建出来数据的下载链接(目前只有下载链接是无法下载的,需要加入验证信息,该问题会在后边提供解决方法)。

现在我们的问题变成了如何自动获取包含数据信息的CSV文件?

手动的步骤为:
打开第四步网址—>下载CSV文件。
那么我们只要实现构建第四步的网址然后自动下载CSV文件即可。

通过观察,我们可以看到第四步的网址为:

https://ladsweb.modaps.eosdis.nasa.gov/search/order/4/MOD021KM--61/2019-12-02..2020-01-28/DB/117.6,35.1,124.8,28.7

我们对该链接的每一部分进行分析:

https://ladsweb.modaps.eosdis.nasa.gov  为网站的主站名
search/order/4    为搜索步骤中的第四步
MOD021KM--61    产品号及版本号
2019-12-02..2020-01-28   所选的日期范围
DB/117.6,35.1,124.8,28.7  研究区范围。研究区的选择有很多方法,DB表示使用Draw Box进行的选取,也可以使用其他方法选择研究区范围。

根据此规律我们就可以自己构建第四步的网址。

要下载该网页中的CSV文件,想到了使用Python+Selenium来对网页进行操作。不同的浏览器情况会有差别,大家可以根据需要自行配置。这里以Chrome浏览器为例。第三部分我们讲解Python+Selenium+ChromeDriver的配置。

至此我们就可以总结出来下载步骤:
a.根据需要构建第四步的下载网址;
b.使用Python+Selenium下载CSV文件;
c.构建遥感数据的下载链接;
d.根据下载链接下载数据。

3.Python+Selenium+ChromeDriver配置

正式下载之前,我们应该配置好Python+Selenium+ChromeDriver环境。
3.1.首先当然是要安装Selenium库(关于selenium的教程网上很多,大家可以深入学习一下):

pip install selenium

3.2.下载chrome浏览器驱动:chromedriver。下载地址:
http://chromedriver.storage.googleapis.com/index.html
或者:http://npm.taobao.org/mirrors/chromedriver/
使用Python自动化、批量化的下载LAADS上的数据_第3张图片
注意,下载的驱动版本应该与你电脑上的chrome浏览器的版本号一致。Windows环境下只有32位的,Chrome的版本是64位的也可以使用。

3.3.解压下载到的压缩包,把chromedriver放入你chrome浏览器的根目录下。
使用Python自动化、批量化的下载LAADS上的数据_第4张图片
3.4.增加环境变量,在系统变量Path中加入chromedriver所在文件夹的地址。例如我在Path中加入:C:\Program Files (x86)\Google\Chrome\Application
使用Python自动化、批量化的下载LAADS上的数据_第5张图片

此时环境已经配置好,下面就开始讲解使用Wget或IDM情况下的下载。

4.使用Python+Selenium调用wget下载数据

NASA官方介绍了很多下载的方法。有直接使用Python脚本、wget下载数据的方法。我们这里通过借鉴官方的下载方法,使用python脚本调用wget来进行数据下载。

首先当然是要安装wget。wget for Windows的下载地址:
https://eternallybored.org/misc/wget/

我们先来看一下使用Wget下载LAADS数据的命令,

wget -e robots=off -m -np -R .html,.tmp -nH --cut-dirs=3 "数据下载链接地址" --header "Authorization: Bearer Your_APP_Key" -P 要下载到你电脑上的位置

参数解释(看不懂也不用担心):
-e robots=off : Bypass the robots.txt file, to allow access to all files in the order;
-m: Enable mirroring options (-r -N -l inf) for recursive download, timestamping & unlimited depth;
-np: Do not recurse into the parent location;
-R .html,.tmp : Reject (do not save) any .html or .tmp files (which are extraneous to the order);
-nH : Do not create a subdirectory with the Host name (ladsweb.modaps.eosdis.nasa.gov);
--cut-dirs=3 : Do not create subdirectories for the first 3 levels ;
--header : Adds the header with your appKey (which is encrypted via SSL);
-P : Specify the directory prefix (may be relative or absolute);

这里给出一个例子,方便大家理解:

wget -e robots=off -m -np -R .html,.tmp -nH --cut-dirs=3 "https://ladsweb.modaps.eosdis.nasa.gov/archive/allData/450/S3A_OL_1_EFR/2020/005/S3A_OL_1_EFR____20200105T014337_20200105T014637_20200106T062806_0179_053_231_2340_LN1_O_NT_002.zip" --header "Authorization: Bearer 00000000-0000-0000-0000-000000000000" -P F:/TestDownload

使用Python+Selenium调用wget下载数据就可以总结为:
a.构建Search网页的网址;
b.python+selenium在Search网页中下载CSV文件;
c.读取CSV文件内容,构建遥感数据的下载链接;
d.python中调用wget根据数据的下载链接进行数据下载。

**注:**如何获取自动下载到的csv文件的文件名。我这里使用的方法是,根据程序运行的时间构建一个文件夹,然后将该文件夹设置为浏览器下载文件的默认位置。下载完成后,在构建的文件夹中使用函数读取下载文件的文件名,获取CSV文件的路径名。

代码如下:

from selenium import webdriver
from time import sleep
from selenium.webdriver.chrome.options import Options
from subprocess import call
from selenium.common.exceptions import NoSuchElementException
import os
import pandas as pd
import time
from datetime import datetime
from apscheduler.schedulers.blocking import BlockingScheduler  

def CSVDown(Driver):
    #找到文本包含csv的标签
    csvElement=Driver.find_element_by_link_text('csv')
    #点击下载
    csvElement.click()
    #留下下载csv文件的时间
    sleep(10)

def MODISDown(FileDir):
    #获取下载的csv文件的文件名
    csvfilename=os.listdir(FileDir)[0]
    #构造文件路径
    csvfilepath=os.path.join(FileDir,csvfilename)
    #读取文件中的值
    csvvalues=pd.read_csv(csvfilepath).values
    #使用wget
    for cv in csvvalues:
        #构建数据的下载链接
        modislink='https://ladsweb.modaps.eosdis.nasa.gov'+cv[1]
        #构建wget命令
        #字符串中要将你的AppKey替换成你的AppKey
        wgetcmd='wget -e robots=off -m -np -R .html,.tmp -nH --cut-dirs=3 "'+modislink+'" --header "Authorization: Bearer 00000000-0000-0000-0000-000000000000" -P F:/TestDownload'
        #使用CMD调用wget进行下载
        call(wgetcmd)


def LocalTime():
    CurrentYear=datetime.now().year
    CurrentMonth=datetime.now().month
    CurrentDay=datetime.now().day
    CurrentHour=datetime.now().hour
    CurrentMinute=datetime.now().minute
    CurrentSecond=datetime.now().second
    return CurrentYear,CurrentMonth,CurrentDay,CurrentHour,CurrentMinute,CurrentSecond


#创建文件夹,命名规则为程序运行的时刻
#将使用selenium下载的文件使用该文件夹存储
Year,Month,Day,Hour,Minute,Second=LocalTime()
csvdir='d:\\'+str(Year)+str(Month)+str(Day)+str(Hour)+str(Minute)+str(Second)
os.mkdir(csvdir)

#配置selenium的参数
options = webdriver.ChromeOptions()
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': csvdir}
options.add_experimental_option('prefs', prefs)
#options.add_argument('--headless')  #有无浏览器界面模式,根据需要设置
driver = webdriver.Chrome(chrome_options=options)

#定义要下载数据的信息
ProductID='MOD021KM--61/' #产品号
#设置数据的起始和截至时间。其实就是根据需要构造一个简单的字符串
StartTime='2019-01-01'  #开始时间
EndTime='2019-01-05'    #截至日期
Area='119.7,32.6,123.1,30.2'  #研究区范围,左上角和右下角。根据需要构造字符串

#根据以上信息构建Search页的网址
url='https://ladsweb.modaps.eosdis.nasa.gov/search/order/4/'+ProductID+StartTime+'..'+EndTime+'/DB/'+Area

#自动打开Search页
driver.get(url)
#浏览器打开Search页后,还要留足时间让服务器进行数据检索
#所以这里sleep50秒,可以根据网速自行设定
#当然也可以判断搜索结果,也就是包含csv的标签是否出现
sleep(20)
#下载csv文件
CSVDown(driver)

#关闭浏览器
driver.quit()

#下载遥感数据
MODISDown(csvdir)

使用该程序时,记得填入自己的APP_Key,替换程序中的00000000-0000-0000-0000-000000000000

程序运行的结果如图:
使用Python自动化、批量化的下载LAADS上的数据_第6张图片

5.使用Python+Selenium调用IDM下载数据

下载数据时我们肯定不能放过IDM这款优秀的下载器,关于如何在在命令行中调用IDM进行下载,我在https://blog.csdn.net/mrzhy1/article/details/104098007这篇文章中有一定的介绍。在此不在赘述。

之前,在LAADS上下载MODIS数据,我从来没有登录过,所以只要我有了数据下链接就可以直接下载数据。但是现在需要进行用户登录了。不过不用担心,只要在IDM中简单设置一下,就可以使用下载链接下载数据的。

打开IDM,在:
下载—>选项—>站点管理器,新建。填入网址:https://urs.earthdata.nasa.gov,然后再填入自己的账号密码,确定。如图:
使用Python自动化、批量化的下载LAADS上的数据_第7张图片

这样配置好之后,其实只用将上方代码中的的’‘MODISDown’'函数简单更改即可:

from selenium import webdriver
from time import sleep
from selenium.webdriver.chrome.options import Options
from subprocess import call
from selenium.common.exceptions import NoSuchElementException
import os
import pandas as pd
import time
from datetime import datetime
from apscheduler.schedulers.blocking import BlockingScheduler 
#IDM的安装位置 
IDM = r"D:\Program Files (x86)\Internet Download Manager\IDMan.exe"
def CSVDown(Driver):
    #找到文本包含csv的标签
    csvElement=Driver.find_element_by_link_text('csv')
    #点击下载
    csvElement.click()
    #留下下载csv文件的时间
    sleep(10)

def MODISDown(FileDir):
    #获取下载的csv文件的文件名
    csvfilename=os.listdir(FileDir)[0]
    #构造文件路径
    csvfilepath=os.path.join(FileDir,csvfilename)
    #读取文件中的值
    csvvalues=pd.read_csv(csvfilepath).values
    #使用wget
    for cv in csvvalues:
        #构建数据的下载链接
        modislink='https://ladsweb.modaps.eosdis.nasa.gov'+cv[1]
        #数据保存地址
        DownPath='F:/TestDownload'
        #调用IDM,将任务加入队列
        call([IDM, '/d',modislink, '/p',DownPath,'/n','/a'])
    #开始下载   
    call([IDM,'/s'])


def LocalTime():
    CurrentYear=datetime.now().year
    CurrentMonth=datetime.now().month
    CurrentDay=datetime.now().day
    CurrentHour=datetime.now().hour
    CurrentMinute=datetime.now().minute
    CurrentSecond=datetime.now().second
    return CurrentYear,CurrentMonth,CurrentDay,CurrentHour,CurrentMinute,CurrentSecond


#创建文件夹,命名规则为程序运行的时刻
#将使用selenium下载的文件使用该文件夹存储
Year,Month,Day,Hour,Minute,Second=LocalTime()
csvdir='d:\\'+str(Year)+str(Month)+str(Day)+str(Hour)+str(Minute)+str(Second)
os.mkdir(csvdir)

#配置selenium的参数
options = webdriver.ChromeOptions()
prefs = {'profile.default_content_settings.popups': 0, 'download.default_directory': csvdir}
options.add_experimental_option('prefs', prefs)
#options.add_argument('--headless')  #有无浏览器界面模式,根据需要设置
driver = webdriver.Chrome(chrome_options=options)

#定义要下载数据的信息
ProductID='MOD021KM--61/' #产品号
#设置数据的起始和截至时间。其实就是根据需要构造一个简单的字符串
StartTime='2019-01-01'  #开始时间
EndTime='2019-01-05'    #截至日期
Area='119.7,32.6,123.1,30.2'  #研究区范围,左上角和右下角。根据需要构造字符串

#根据以上信息构建Search页的网址
url='https://ladsweb.modaps.eosdis.nasa.gov/search/order/4/'+ProductID+StartTime+'..'+EndTime+'/DB/'+Area

#自动打开Search页
driver.get(url)
#浏览器打开Search页后,还要留足时间让服务器进行数据检索
#所以这里sleep50秒,可以根据网速自行设定
#当然也可以判断搜索结果,也就是包含csv的标签是否出现
sleep(20)
#下载csv文件
CSVDown(driver)

#关闭浏览器
driver.quit()

#下载遥感数据
MODISDown(csvdir)

运行结果如图:
使用Python自动化、批量化的下载LAADS上的数据_第8张图片

6.总结

我个人比较推荐使用Python+IDM的下载方法。

a.或许你可以设置一个定时任务,利用本博客的思路实现每天定时下载数据的功能。

b.大家在下载数据之前,还是要手动进行一遍下载步骤。根据实际情况修改代码来下载所需数据。

c.大家也可以通过这篇博客,根据自己的需要,找到属于自己下载数据的灵感。

d.博客中如有错误,希望大家不吝赐教。

你可能感兴趣的:(使用Python自动化、批量化的下载LAADS上的数据)