使用Python3下載Phytozome數(shù)據(jù)庫(kù)

Phytozome 作為專(zhuān)門(mén)收錄植物基因組的網(wǎng)站,在基因組數(shù)據(jù)的下載、查詢(xún)、可視化瀏覽等方面做的都很不錯(cuò)。
為了下載整個(gè)Phytozome數(shù)據(jù)庫(kù),我先后使用了requests庫(kù),json解析器,ElementTree解析器,hashlib庫(kù)等功能。
實(shí)現(xiàn)了自動(dòng)化下載并解析最新數(shù)據(jù)庫(kù)結(jié)構(gòu),MD5值校驗(yàn)本地文件,下載進(jìn)度可恢復(fù)等功能。

為了方便大家使用,我先奉上我花了兩天時(shí)間寫(xiě)的代碼。

代碼后面附上使用方式。

以下代碼我已存取至GITHUB,地址為:

最新的為1.2版本,請(qǐng)直接去github取用,解決了老式登錄方法無(wú)效的問(wèn)題

https://github.com/liudab/phytozomedownloader

歡迎取用,如果要轉(zhuǎn)發(fā)請(qǐng)?jiān)儐?wèn)本人。

# -*- coding: utf-8 -*-
"""
Created on Tue Jul 30 20:33:58 2019

@author: Bohan
"""

import requests,json,hashlib,os
from xml.etree import ElementTree
#引入requests。
session = requests.session()

headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36'
}
#add headers加請(qǐng)求頭,前面有說(shuō)過(guò)加請(qǐng)求頭是為了模擬瀏覽器正常的訪問(wèn),避免被反爬蟲(chóng)。
data={}
data['login']='XXXXXX@XXXXX.com'     #這里替換成你自己的賬戶名Replace this with you ACCOUNTNAME in phytozome.jgi.doe.gov
data['password']='XXXXXXXXXXXXXX'       #這里替換成你自己的密碼Replace this with you PASSWORD in phytozome.jgi.doe.gov

def sign_in():
    url = 'https://signon-old.jgi.doe.gov/signon/create'     #把登錄的網(wǎng)址賦值給URL sign_in URL
    session.post(url, headers=headers, data=data)
    cookies_dict = requests.utils.dict_from_cookiejar(session.cookies)
    cookies_str = json.dumps(cookies_dict)
    f = open('cookies.txt', 'w')
    f.write(cookies_str)
    f.close()
     # 以上7行代碼,是登錄網(wǎng)站并存儲(chǔ)cookies,signin the phytozome and save cookies
def cookies_read():
    cookies_txt = open('cookies.txt', 'r')
    cookies_dict = json.loads(cookies_txt.read())
    cookies = requests.utils.cookiejar_from_dict(cookies_dict)
    return (cookies)
    # 以上4行代碼,是cookies讀取,read local cookies

def md5sum(filepath):
    fd = open(filepath,"rb")  
    fcont = fd.read()
    fd.close()           
    fmd5 = str(hashlib.md5(fcont).hexdigest())
    return fmd5
#定義一個(gè)md5sum函數(shù),返回校驗(yàn)值,def a function md5sum, to check and return md5 value of a certain file

def sdownloadfile(link,filepath,md5):
    print('文件:'+link+' 正在下載')      #you can use print('file:'+link+' is downloading') as englsih user
    downloadfile=session.get(link)
    with open(filepath,'wb') as f:
        f.write(downloadfile.content)
    fmd5=md5sum(filepath)
    if fmd5==md5:
        print('文件:'+filepath+' 下載并校驗(yàn)成功!')    #you can use print('file:'+filepath+' is downloaded and it is intact!') as englsih user
    else:
        print('文件:'+filepath+' 校驗(yàn)失??!')         #you can use print('file:'+filepath+' is failed in md5sum!') as englsih user
#定義一個(gè)sdownloadfile函數(shù),從link下載文件,存儲(chǔ)到filepath,并利用md5值對(duì)下載完成的文件進(jìn)行MD5校驗(yàn), download file and check it integrity

def createpath(file_path):
    try:
        if not os.path.exists(file_path):
            print ('文件夾',file_path,'不存在,重新建立')    #print ('folder',file_path,'is not exist, created it')
            #os.mkdir(file_path)
            os.makedirs(file_path)
    except IOError as e:
        print ('文件操作失敗',e)      #print ('IOError',e)
    except Exception as e:
        print ('錯(cuò)誤 :',e)    #print ('Error',e)
#定義一個(gè)createpath函數(shù),檢測(cè)所在目錄是否存在,不存在則建立文件夾,check filedirectory exisit or not, if not create that folder
 

def getxml():
    global fileurl
    fileurl=[]
    PHYTOALL='Phytozome'
    xmldata=session.get('https://genome.jgi.doe.gov/portal/ext-api/downloads/get-directory?organism=Phytozome&organizedByFileType=false')
    #輸入API指定的版本名稱(chēng)
    with open('./'+PHYTOALL+'.xml','wb') as xf:
        xf.write(xmldata.content)
    #下載對(duì)應(yīng)版本的官方xml文件
    xmlDoc = ElementTree.parse('./'+PHYTOALL+'.xml')    #讀取并使用ElementTree解析PhytozomeV12.xml文件,并命名為xmlDoc
    folderl1 = xmlDoc.findall('folder')    #使用findall功能找出子一級(jí)folder列表
    print('目前數(shù)據(jù)庫(kù)中有以下版本:\n')         #print('The database have these Versions:\n')
    number=1
    for folderl1x in folderl1:     #遍歷一級(jí)folder列表
        print(str(number)+'. '+folderl1x.attrib['name'])
        number=number+1
    pick=input('請(qǐng)輸入你想下載的數(shù)據(jù)庫(kù),用數(shù)字表示:\n例如:2   輸入后請(qǐng)回車(chē)\n')           #pick=input('Pleas choose which version you want,input with number:\nFor example:2   After your input,pree Enter.\n')
    folderl1name =folderl1[int(pick)-1]
    folderl2 = folderl1name.findall('folder')     #使用findall功能找出子二級(jí)folder列表
    folderl2f = folderl1name.findall('file')
    for folderl2fname in folderl2f:
        folderpathl2 = "./"+ str(folderl1name.get('name'))+ "/" 
        fileurl.append(folderpathl2)
        fileurl.append(folderl2fname.get('filename'))
        fileurl.append('https://genome.jgi.doe.gov'+folderl2fname.get('url'))
        fileurl.append(folderl2fname.get('md5'))
    for folderl2name in folderl2:    #遍歷二級(jí)folder列表
        folderl3 = folderl2name.findall('folder')    #使用findall功能找出子三級(jí)folder列表
        folderl3f = folderl2name.findall('file')
        for folderl3fname in folderl3f:
            folderpathl3 = "./"+ str(folderl1name.get('name'))+"/"+ str(folderl2name.get('name')) +  "/" 
            fileurl.append(folderpathl3)
            fileurl.append(folderl3fname.get('filename'))
            fileurl.append('https://genome.jgi.doe.gov'+folderl3fname.get('url'))
            fileurl.append(folderl3fname.get('md5'))
        for folderl3name in folderl3:     #遍歷三級(jí)folder列表
            folderl4 = folderl3name.findall('folder')    #使用findall功能找出子4級(jí)folder列表
            folderl4f = folderl3name.findall('file')
            for folderl4fname in folderl4f:
                folderpathl4 = "./"+ str(folderl1name.get('name'))+"/"+ str(folderl2name.get('name')) +  "/" +str(folderl3name.get('name'))+  "/"
                fileurl.append(folderpathl4)
                fileurl.append(folderl4fname.get('filename'))
                fileurl.append('https://genome.jgi.doe.gov'+folderl4fname.get('url'))
                fileurl.append(folderl4fname.get('md5'))
            for folderl4name in folderl4:     #遍歷4級(jí)folder列表
                folderl5 = folderl4name.findall('folder')    #使用findall功能找出子5級(jí)folder列表
                folderl5f = folderl4name.findall('file')
                for folderl5fname in folderl5f:
                    folderpathl5 = "./"+ str(folderl1name.get('name')) + "/" + str(folderl2name.get('name')) + "/" + str(folderl3name.get('name')) + "/"+ str(folderl4name.get('name')) + "/"
                    fileurl.append(folderpathl5)
                    fileurl.append(folderl5fname.get('filename'))
                    fileurl.append('https://genome.jgi.doe.gov'+folderl5fname.get('url'))
                    fileurl.append(folderl5fname.get('md5'))
    file = open("./genome.links","w")
    file.write(str(fileurl))
    file.close()
    return fileurl
#解析官方xml文件,將對(duì)應(yīng)文件名稱(chēng)、路徑以及MD5值存取至genom.links文件,格式為列表形式,4個(gè)數(shù)值循環(huán)存儲(chǔ),1路徑,2文件名,3URL,4MD5值

def gettasklist():
    global tasklist
    tasklist={}
    for i in range(int(len(fileurl)/4)):
        onefilelist=[]
        onefilelist.append(fileurl[i*4+2])
        onefilelist.append(fileurl[i*4]+fileurl[i*4+1])
        onefilelist.append(fileurl[i*4+3])
        tasklist[i]=onefilelist
    return tasklist
#合并文件路徑和文件名,合成tasklist,格式為1URL,2路徑+文件名,3MD5值

sign_in()    #登錄
getxml()    #GETXML
gettasklist()   #GETtasklist
for i in range(int(len(fileurl)/4)):
    createpath(fileurl[i*4])     #解析官方xml文件,在根目錄下創(chuàng)建所有子目錄

def paralleldownload():
    for j in range(int(len(tasklist))):
        try:
            if md5sum(tasklist[j][1]) != tasklist[j][2]:
                sdownloadfile(tasklist[j][0],tasklist[j][1],tasklist[j][2])
                print('共計(jì)'+str(int(len(tasklist)))+'個(gè)文件,'+'目前下載完第'+str(j+1)+'個(gè)文件')  #print('There are total'+str(int(len(tasklist)))+'files,'+'We are downloading the number:'+str(j+1))
            else:
                print('第'+str(j+1)+'個(gè)文件已存在且與本地文件一致')    #print('The No.'+str(j+1)+'file is already existing, and it don't need to be download again')
        except FileNotFoundError as e:
            sdownloadfile(tasklist[j][0],tasklist[j][1],tasklist[j][2])
            print('共計(jì)'+str(int(len(tasklist)))+'個(gè)文件,'+'目前下載完第'+str(j+1)+'個(gè)文件')  #print('There are total'+str(int(len(tasklist)))+'files,'+'We are downloading the number:'+str(j+1))
paralleldownload()

如何使用:

1.復(fù)制本文第一部分內(nèi)容所有代碼,存為download.py。

2.在以下內(nèi)容處編輯,加入你自己的賬戶名和密碼。

data={}
data['login']='XXXXXX@XXXXX.com'     #這里替換成你自己的賬戶名Replace this with you ACCOUNTNAME in phytozome.jgi.doe.gov
data['password']='XXXXXXXXXXXXXX'       #這里替換成你自己的密碼Replace this with you PASSWORD in phytozome.jgi.doe.gov

3.直接輸入以下代碼,開(kāi)始運(yùn)行程序。

python3 download.py

程序運(yùn)行起來(lái)大概是這樣的

目前數(shù)據(jù)庫(kù)中有以下版本:

1. PhytozomeV9
2. PhytozomeV13
3. PhytozomeV12_unrestricted
4. PhytozomeV12
5. PhytozomeV11
6. PhytozomeV10
請(qǐng)輸入你想下載的數(shù)據(jù)庫(kù),用數(shù)字表示:
例如:2   輸入后請(qǐng)回車(chē)
2
第1個(gè)文件已存在且與本地文件一致
第2個(gè)文件已存在且與本地文件一致
第3個(gè)文件已存在且與本地文件一致
第4個(gè)文件已存在且與本地文件一致
第5個(gè)文件已存在且與本地文件一致
第6個(gè)文件已存在且與本地文件一致
第7個(gè)文件已存在且與本地文件一致
第8個(gè)文件已存在且與本地文件一致
第9個(gè)文件已存在且與本地文件一致
第10個(gè)文件已存在且與本地文件一致
第11個(gè)文件已存在且與本地文件一致
第12個(gè)文件已存在且與本地文件一致
第13個(gè)文件已存在且與本地文件一致
第14個(gè)文件已存在且與本地文件一致
第15個(gè)文件已存在且與本地文件一致
第16個(gè)文件已存在且與本地文件一致
第17個(gè)文件已存在且與本地文件一致
第18個(gè)文件已存在且與本地文件一致
第19個(gè)文件已存在且與本地文件一致
第20個(gè)文件已存在且與本地文件一致
第21個(gè)文件已存在且與本地文件一致
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/5bfc65e246d1e61e989e5784/ZmaysPHB47_513_v1.0.fa.gz 正在下載
文件:./PhytozomeV13/ZmaysPHB47/v1.1/assembly/ZmaysPHB47_513_v1.0.fa.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第22個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/5bfc65de46d1e61e989e577c/ZmaysPHB47_513_v1.1.transcript_primaryTranscriptOnly.fa.gz 正在下載
文件:./PhytozomeV13/ZmaysPHB47/v1.1/annotation/ZmaysPHB47_513_v1.1.transcript_primaryTranscriptOnly.fa.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第23個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/5bfc65df46d1e61e989e577e/ZmaysPHB47_513_v1.1.transcript.fa.gz 正在下載
文件:./PhytozomeV13/ZmaysPHB47/v1.1/annotation/ZmaysPHB47_513_v1.1.transcript.fa.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第24個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/5bfc65dd46d1e61e989e5779/ZmaysPHB47_513_v1.1.repeatmasked_assembly_v1.0.gff3.gz 正在下載
文件:./PhytozomeV13/ZmaysPHB47/v1.1/annotation/ZmaysPHB47_513_v1.1.repeatmasked_assembly_v1.0.gff3.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第25個(gè)文件







\

另外,如果你想通過(guò)nohup的方式

讓我提供的腳本持續(xù)在后臺(tái)運(yùn)行直到任務(wù)完成。

你可以這樣做:

1.復(fù)制本文第一部分內(nèi)容所有代碼,存為downloadnohup.py。

2.在以下內(nèi)容處編輯,加入你自己的賬戶名和密碼。

data={}
data['login']='XXXXXX@XXXXX.com'     #這里替換成你自己的賬戶名Replace this with you ACCOUNTNAME in phytozome.jgi.doe.gov
data['password']='XXXXXXXXXXXXXX'       #這里替換成你自己的密碼Replace this with you PASSWORD in phytozome.jgi.doe.gov

3.在以下內(nèi)容處編輯,加入你自己選擇的數(shù)據(jù)庫(kù)版本名稱(chēng)。

本腳本是通過(guò)getxml()函數(shù)中的pick值來(lái)選擇的。
因此你需要更改代碼中的pick值。

pick=input('請(qǐng)輸入你想下載的數(shù)據(jù)庫(kù),用數(shù)字表示:\n例如:2   輸入后請(qǐng)回車(chē)\n')

把上面的代碼改成這樣:

pick=2

4.直接輸入以下代碼,開(kāi)始運(yùn)行程序。

nohup python3 -u downloadnohup.py &>nohup.out&        #后臺(tái)運(yùn)行腳本并將屏幕輸出實(shí)時(shí)加入nohup.out文件

5.程序后臺(tái)運(yùn)行時(shí),通過(guò)查看nohup.out監(jiān)視進(jìn)度。

tail -fn 50 nohup.out             #查看最近50行輸出內(nèi)容

你大概能看到這樣的結(jié)果

文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/583cd9997ded5e2d305c36db/ZmaysPH207_443_v1.1.protein.fa.gz 正在下載
文件:./PhytozomeV13/ZmaysPH207/v1.1/annotation/ZmaysPH207_443_v1.1.protein.fa.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第43個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/583cd9997ded5e2d305c36dc/ZmaysPH207_443_v1.1.gene_exons.gff3.gz 正在下載
文件:./PhytozomeV13/ZmaysPH207/v1.1/annotation/ZmaysPH207_443_v1.1.gene_exons.gff3.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第44個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/583cd99b7ded5e2d305c36e0/ZmaysPH207_443_v1.1.gene.gff3.gz 正在下載
文件:./PhytozomeV13/ZmaysPH207/v1.1/annotation/ZmaysPH207_443_v1.1.gene.gff3.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第45個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/58a238d27ded5e341aa7f858/ZmaysPH207_443_v1.1.defline.txt 正在下載
文件:./PhytozomeV13/ZmaysPH207/v1.1/annotation/ZmaysPH207_443_v1.1.defline.txt 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第46個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/583cd99a7ded5e2d305c36dd/ZmaysPH207_443_v1.1.cds_primaryTranscriptOnly.fa.gz 正在下載
文件:./PhytozomeV13/ZmaysPH207/v1.1/annotation/ZmaysPH207_443_v1.1.cds_primaryTranscriptOnly.fa.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第47個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/583cd9997ded5e2d305c36da/ZmaysPH207_443_v1.1.cds.fa.gz 正在下載
文件:./PhytozomeV13/ZmaysPH207/v1.1/annotation/ZmaysPH207_443_v1.1.cds.fa.gz 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第48個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/583cd99a7ded5e2d305c36df/ZmaysPH207_443_v1.1.annotation_info.txt 正在下載
文件:./PhytozomeV13/ZmaysPH207/v1.1/annotation/ZmaysPH207_443_v1.1.annotation_info.txt 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第49個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/5c01c6de46d1e61e989ea5b1/Zmays_493_RefGen_V4.readme.txt 正在下載
文件:./PhytozomeV13/Zmays/RefGen_V4/Zmays_493_RefGen_V4.readme.txt 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第50個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/5c01c6de46d1e61e989ea5af/Zmays_493_RefGen_V4.DataReleasePolicy.html 正在下載
文件:./PhytozomeV13/Zmays/RefGen_V4/Zmays_493_RefGen_V4.DataReleasePolicy.html 下載并校驗(yàn)成功!
共計(jì)2961個(gè)文件,目前下載完第51個(gè)文件
文件:https://genome.jgi.doe.gov/portal/ext-api/downloads/get_tape_file?blocking=true&url=/Phytozome/download/_JAMO/5c83121846d1e64ae3ba2bf2/Zmays_493_APGv4.softmasked.fa.gz 正在下載

使用過(guò)程中有什么問(wèn)題可以留言或者私信,大家可以共同學(xué)習(xí)。

改天我會(huì)更新我是如何設(shè)計(jì)這個(gè)程序,怎么用到這些功能的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容