使用Python3下载Phytozome数据库

Phytozome 作为专门收录植物基因组的网站,在基因组数据的下载、查询、可视化浏览等方面做的都很不错。
为了下载整个Phytozome数据库,我先后使用了requests库,json解析器,ElementTree解析器,hashlib库等功能。
实现了自动化下载并解析最新数据库结构,MD5值校验本地文件,下载进度可恢复等功能。

为了方便大家使用,我先奉上我花了两天时间写的代码。

代码后面附上使用方式。

以下代码我已存取至GITHUB,地址为:

最新的为1.2版本,请直接去github取用,解决了老式登录方法无效的问题

https://github.com/liudab/phytozomedownloader

欢迎取用,如果要转发请询问本人。

# -*- 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加请求头,前面有说过加请求头是为了模拟浏览器正常的访问,避免被反爬虫。
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'     #把登录的网址赋值给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行代码,是登录网站并存储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
#定义一个md5sum函数,返回校验值,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+' 下载并校验成功!')    #you can use print('file:'+filepath+' is downloaded and it is intact!') as englsih user
    else:
        print('文件:'+filepath+' 校验失败!')         #you can use print('file:'+filepath+' is failed in md5sum!') as englsih user
#定义一个sdownloadfile函数,从link下载文件,存储到filepath,并利用md5值对下载完成的文件进行MD5校验, 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 ('错误 :',e)    #print ('Error',e)
#定义一个createpath函数,检测所在目录是否存在,不存在则建立文件夹,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指定的版本名称
    with open('./'+PHYTOALL+'.xml','wb') as xf:
        xf.write(xmldata.content)
    #下载对应版本的官方xml文件
    xmlDoc = ElementTree.parse('./'+PHYTOALL+'.xml')    #读取并使用ElementTree解析PhytozomeV12.xml文件,并命名为xmlDoc
    folderl1 = xmlDoc.findall('folder')    #使用findall功能找出子一级folder列表
    print('目前数据库中有以下版本:\n')         #print('The database have these Versions:\n')
    number=1
    for folderl1x in folderl1:     #遍历一级folder列表
        print(str(number)+'. '+folderl1x.attrib['name'])
        number=number+1
    pick=input('请输入你想下载的数据库,用数字表示:\n例如:2   输入后请回车\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功能找出子二级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:    #遍历二级folder列表
        folderl3 = folderl2name.findall('folder')    #使用findall功能找出子三级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:     #遍历三级folder列表
            folderl4 = folderl3name.findall('folder')    #使用findall功能找出子4级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级folder列表
                folderl5 = folderl4name.findall('folder')    #使用findall功能找出子5级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文件,将对应文件名称、路径以及MD5值存取至genom.links文件,格式为列表形式,4个数值循环存储,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文件,在根目录下创建所有子目录

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('共计'+str(int(len(tasklist)))+'个文件,'+'目前下载完第'+str(j+1)+'个文件')  #print('There are total'+str(int(len(tasklist)))+'files,'+'We are downloading the number:'+str(j+1))
            else:
                print('第'+str(j+1)+'个文件已存在且与本地文件一致')    #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('共计'+str(int(len(tasklist)))+'个文件,'+'目前下载完第'+str(j+1)+'个文件')  #print('There are total'+str(int(len(tasklist)))+'files,'+'We are downloading the number:'+str(j+1))
paralleldownload()

如何使用:

1.复制本文第一部分内容所有代码,存为download.py。

2.在以下内容处编辑,加入你自己的账户名和密码。

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.直接输入以下代码,开始运行程序。

python3 download.py

程序运行起来大概是这样的

目前数据库中有以下版本:

1. PhytozomeV9
2. PhytozomeV13
3. PhytozomeV12_unrestricted
4. PhytozomeV12
5. PhytozomeV11
6. PhytozomeV10
请输入你想下载的数据库,用数字表示:
例如:2   输入后请回车
2
第1个文件已存在且与本地文件一致
第2个文件已存在且与本地文件一致
第3个文件已存在且与本地文件一致
第4个文件已存在且与本地文件一致
第5个文件已存在且与本地文件一致
第6个文件已存在且与本地文件一致
第7个文件已存在且与本地文件一致
第8个文件已存在且与本地文件一致
第9个文件已存在且与本地文件一致
第10个文件已存在且与本地文件一致
第11个文件已存在且与本地文件一致
第12个文件已存在且与本地文件一致
第13个文件已存在且与本地文件一致
第14个文件已存在且与本地文件一致
第15个文件已存在且与本地文件一致
第16个文件已存在且与本地文件一致
第17个文件已存在且与本地文件一致
第18个文件已存在且与本地文件一致
第19个文件已存在且与本地文件一致
第20个文件已存在且与本地文件一致
第21个文件已存在且与本地文件一致
文件: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 下载并校验成功!
共计2961个文件,目前下载完第22个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第23个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第24个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第25个文件







\

另外,如果你想通过nohup的方式

让我提供的脚本持续在后台运行直到任务完成。

你可以这样做:

1.复制本文第一部分内容所有代码,存为downloadnohup.py。

2.在以下内容处编辑,加入你自己的账户名和密码。

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.在以下内容处编辑,加入你自己选择的数据库版本名称。

本脚本是通过getxml()函数中的pick值来选择的。
因此你需要更改代码中的pick值。

pick=input('请输入你想下载的数据库,用数字表示:\n例如:2   输入后请回车\n')

把上面的代码改成这样:

pick=2

4.直接输入以下代码,开始运行程序。

nohup python3 -u downloadnohup.py &>nohup.out&        #后台运行脚本并将屏幕输出实时加入nohup.out文件

5.程序后台运行时,通过查看nohup.out监视进度。

tail -fn 50 nohup.out             #查看最近50行输出内容

你大概能看到这样的结果

文件: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 下载并校验成功!
共计2961个文件,目前下载完第43个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第44个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第45个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第46个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第47个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第48个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第49个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第50个文件
文件: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 下载并校验成功!
共计2961个文件,目前下载完第51个文件
文件: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 正在下载

使用过程中有什么问题可以留言或者私信,大家可以共同学习。

改天我会更新我是如何设计这个程序,怎么用到这些功能的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352