Biopython学习笔记(四)访问NCBI Entrez数据库

Entrez是一个检索系统,供人们访问NCBI里各个数据库。比如说:PubMed, GenBank, GEO等等。你可以通过网站来搜索你想要的内容:https://www.ncbi.nlm.nih.gov/search/。当然你也可以使用Biopython的Bio.Entrez模块来访问Entrez。

Bio.Entrez利用EUtils,包含8个工具,具体请见https://www.ncbi.nlm.nih.gov/books/NBK25501/。每一个工具都对应了Bio.Entrez里的一个python的功能。

EUtils返回的结果通常是XML格式文件,有4种方法来解析这种类型的输入文件:
(1)使用 Bio.Entrez解析器将XML解析成Python对象)。
(2)使用Python标准库中的DOM解析器。
(3)使用Python标准库中的SAX解析器。
(4)把XML输出当做原始的文本文件,通过字符串查找和处理来进行解析。

NCBI使用DTD (Document Type Definition)文件来描述XML文件中信息的结构。大多数NCBI使用的DTD文件格式都包含在了Biopython包里。当NCBI Entrez读入一个XML格式的文件的时候,Bio.Entrez将会使用DTD文件。

Entrez 简介

在利用Biopython访问Entrez之前,你需要阅读使用规范。其实就是一些关于你的访问时间,以及你的访问请求次数一些限制。

使用email参数,这样如果遇到什么问题,NCBI可以通过邮件联系到你。你可以在每次请求Entrez的时候明确的设置这个参数(例如,在参数列表中包含 email="A.N.Other@example.com" ),或者你也可以设置一个全局的email 地址(切记千万别随便填邮箱!):

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"

注意要控制你寄几!别下载海量的数据!具体为什么我也不知道。。。

EInfo: 获取Entrez数据库的信息

EInfo为每个NCBI的数据库提供了条目索引、最近更新的时间、可用的链接。此外,可以使用EInfo获得Entrez所有数据库名字的列表:

>>> from Bio import Entrez
>>> Entrez.email = "**************"
>>> handle = Entrez.einfo()
>>> result = handle.read()
>>> handle.close()
>>> print(result)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE eInfoResult PUBLIC "-//NLM//DTD einfo 20190110//EN" "https://eutils.ncbi.nlm.nih.gov/eutils/dtd/20190110/einfo.dtd">
<eInfoResult>
<DbList>

    <DbName>pubmed</DbName>
    <DbName>protein</DbName>
    <DbName>nuccore</DbName>
    <DbName>ipg</DbName>
    <DbName>nucleotide</DbName>
    <DbName>structure</DbName>
    <DbName>sparcle</DbName>
    <DbName>genome</DbName>
    <DbName>annotinfo</DbName>
    <DbName>assembly</DbName>
    <DbName>bioproject</DbName>
    <DbName>biosample</DbName>
    <DbName>blastdbinfo</DbName>
    <DbName>books</DbName>
    <DbName>cdd</DbName>
    <DbName>clinvar</DbName>
    <DbName>gap</DbName>
    <DbName>gapplus</DbName>
    <DbName>grasp</DbName>
    <DbName>dbvar</DbName>
    <DbName>gene</DbName>
    <DbName>gds</DbName>
    <DbName>geoprofiles</DbName>
    <DbName>homologene</DbName>
    <DbName>medgen</DbName>
    <DbName>mesh</DbName>
    <DbName>ncbisearch</DbName>
    <DbName>nlmcatalog</DbName>
    <DbName>omim</DbName>
    <DbName>orgtrack</DbName>
    <DbName>pmc</DbName>
    <DbName>popset</DbName>
    <DbName>probe</DbName>
    <DbName>proteinclusters</DbName>
    <DbName>pcassay</DbName>
    <DbName>biosystems</DbName>
    <DbName>pccompound</DbName>
    <DbName>pcsubstance</DbName>
    <DbName>seqannot</DbName>
    <DbName>snp</DbName>
    <DbName>sra</DbName>
    <DbName>taxonomy</DbName>
    <DbName>biocollections</DbName>
    <DbName>gtr</DbName>
</DbList>

</eInfoResult>

上面这个result就是包含了所有列表的xml格式文件。使用 Bio.Entrez解析器,可以直接将这个XML读入到一个Python对象里面去:

>>> from Bio import Entrez
>>> handle = Entrez.einfo()
>>> record = Entrez.read(handle)
#现在 record 是一个有着确定键值的字典:
>>> record.keys()
dict_keys(['DbList'])

我们可以看一下这个键对应的值就是存储了上面得到的数据库名字的列表:

>>> record["DbList"]
['pubmed', 'protein', 'nuccore', 'ipg', 'nucleotide', 'structure', 'sparcle', 'genome', 'annotinfo', 'assembly', 'bioproject', 'biosample', 'blastdbinfo', 'books', 'cdd', 'clinvar', 'gap', 'gapplus', 'grasp', 'dbvar', 'gene', 'gds', 'geoprofiles', 'homologene', 'medgen', 'mesh', 'ncbisearch', 'nlmcatalog', 'omim', 'orgtrack', 'pmc', 'popset', 'probe', 'proteinclusters', 'pcassay', 'biosystems', 'pccompound', 'pcsubstance', 'seqannot', 'snp', 'sra', 'taxonomy', 'biocollections', 'gtr']

对于每一个数据库,我们可以用EInfo获得更多的信息:

>>> from Bio import Entrez
>>> Entrez.email = "×××××××××××××"
>>> handle = Entrez.einfo(db="pubmed")
>>> record = Entrez.read(handle)
>>> record["DbInfo"]["Description"]
'PubMed bibliographic record'
>>> record["DbInfo"]["Count"]
'30838754'
>>> record["DbInfo"]["LastUpdate"]
'2020/04/05 07:33'

上面我们通过 record["DbInfo"].keys() 获取存储在这个记录里面的信息。这里面最有用的信息之一是一个叫ESearch的可用的搜索值列表:

>>> for field in record["DbInfo"]["FieldList"]:
...     print("%(Name)s, %(FullName)s, %(Description)s" % field)
... 
ALL, All Fields, All terms from all searchable fields
UID, UID, Unique number assigned to publication
FILT, Filter, Limits the records
TITL, Title, Words in title of publication
WORD, Text Word, Free text associated with publication
MESH, MeSH Terms, Medical Subject Headings assigned to publication
MAJR, MeSH Major Topic, MeSH terms of major importance to publication
AUTH, Author, Author(s) of publication
JOUR, Journal, Journal abbreviation of publication
AFFL, Affiliation, Author's institutional affiliation and address
......

这个列表有点长,就不都拷过来了。这个表可以间接的告诉你在使用PubMed的时候,你可以通过 Jones[AUTH] 搜索作者,或者通过 Sanger[AFFL] 将作者范围限制在Sanger Centre。也就是过滤的作用。

ESearch: 搜索Entrez数据库

Bio.Entrez.esearch()功能可以在任何数据库里搜索。比如:我想在pubMed里搜索与"Biopython"相关的文献:

>>> from Bio import Entrez
>>> handle = Entrez.esearch(db="pubmed", term="biopython")
>>> record = Entrez.read(handle)
>>> record["IdList"]
['32044951', '31762715', '31278684', '31069053', '30013827', '29641230', '28011774', '24929426', '24497503', '24267035', '24194598', '23842806', '23157543', '22909249', '22399473', '21666252', '21210977', '20015970', '19811691', '19773334']

在输出的结果中,我们可以看到20个PubMed的IDs,后面会讲到如何来获取这些文献。

你也可以通过ESearch来搜索GenBank里某一个基因,比如说以植物Cypripedioideae orchids的matK基因为例:

#下面的括号里三个参数分别是:数据库、要搜索的物种和基因、返回的类型为Accession number。如果不指定返回类型,则默认为gi number。
>>> handle = Entrez.esearch(db="nucleotide", term="Cypripedioideae[Orgn] AND matK[Gene]", idtype="acc")
>>> record = Entrez.read(handle)
>>> record["Count"]
'539'
>>> record["IdList"]
['MN016934.1', 'NC_045279.1', 'NC_045278.1', 'NC_045400.1', 'MN602053.1', 'MN535015.1', 'MN535014.1', 'KX886268.1', 'KX886267.1', 'KX886266.1', 'KX886265.1', 'KX886264.1', 'KX886263.1', 'KX886262.1', 'KX886261.1', 'KX886260.1', 'KX886259.1', 'KX886258.1', 'KX886257.1', 'KX886256.1']

注意,如果你不用 Cypripedioideae[Orgn] 这样来限制物种的名字,也可以使用NCBI的taxon ID,像txid158330[Orgn]这样。同样的,后面会讲到如何下载这些GenBank的记录的信息。

你还可以获取某一个方面杂志的列表:

>>> handle = Entrez.esearch(db="nlmcatalog", term="computational[Journal]", retmax="20") #最多返回20个
>>> record = Entrez.read(handle)
>>> print("{} computational journals found".format(record["Count"]))
172 computational journals found
>>> print("The first 20 are\n{}".format(record["IdList"])) #打印出的是杂志的ID
The first 20 are
['101765300', '101759185', '101752828', '101755127', '101753951', '101753371', '101740904', '101737789', '101736625', '101728813', '101723217', '101754869', '101723351', '101719151', '101718871', '101717513', '101708081', '101707097', '101724357', '101721723']

ESummary: 通过主要的IDs来获取摘要

在Biopython中,ESummary功能可以通过ID获得更多的信息:

>>> from Bio import Entrez
>>> handle = Entrez.esummary(db="nlmcatalog", id="101660833")
>>> record = Entrez.read(handle)
>>> info = record[0]["TitleMainList"][0]
>>> print("Journal info\nid: {}\nTitle: {}".format(record[0]["Id"], info["Title"]))
Journal info
id: 101660833
Title: IEEE transactions on computational imaging.

EFetch: 从Entrez下载更多的记录

这里就是重点了,上面我们搜索到了想要的信息,那么如何将它们下载下来呢?
使用 Bio.Entrez.efetch()从Entrez下载特定的某种格式的时候,需要 rettype 和或者 retmode 参数。对于不同数据库类型不同的搭配在下面的网页中有描述: NCBI efetch webpage (例如: literature, sequences and taxonomy)。

一种常用的用法是下载FASTA或者GenBank/GenPept的文本格式 (接着可以使用 Bio.SeqIO 来解析)。举例:通过 Bio.Entrez.efetch 从GenBank下载ID为EU490707 的基因:

>>> from Bio import Entrez
>>> handle = Entrez.efetch(db="nucleotide", id="EU490707", rettype="gb", retmode="text")
>>> print(handle.read())
LOCUS       EU490707                1302 bp    DNA     linear   PLN 26-JUL-2016
DEFINITION  Selenipedium aequinoctiale maturase K (matK) gene, partial cds;
            chloroplast.
ACCESSION   EU490707
VERSION     EU490707.1
KEYWORDS    .
SOURCE      chloroplast Selenipedium aequinoctiale
  ORGANISM  Selenipedium aequinoctiale
            Eukaryota; Viridiplantae; Streptophyta; Embryophyta; Tracheophyta;
            Spermatophyta; Magnoliopsida; Liliopsida; Asparagales; Orchidaceae;
            Cypripedioideae; Selenipedium.
REFERENCE   1  (bases 1 to 1302)
  AUTHORS   Neubig,K.M., Whitten,W.M., Carlsward,B.S., Blanco,M.A., Endara,L.,
            Williams,N.H. and Moore,M.
  TITLE     Phylogenetic utility of ycf1 in orchids: a plastid gene more
            variable than matK
  JOURNAL   Plant Syst. Evol. 277 (1-2), 75-84 (2009)
REFERENCE   2  (bases 1 to 1302)
  AUTHORS   Neubig,K.M., Whitten,W.M., Carlsward,B.S., Blanco,M.A.,
            Endara,C.L., Williams,N.H. and Moore,M.J.
  TITLE     Direct Submission
  JOURNAL   Submitted (14-FEB-2008) Department of Botany, University of
            Florida, 220 Bartram Hall, Gainesville, FL 32611-8526, USA
FEATURES             Location/Qualifiers
     source          1..1302
                     /organism="Selenipedium aequinoctiale"
                     /organelle="plastid:chloroplast"
                     /mol_type="genomic DNA"
                     /specimen_voucher="FLAS:Blanco 2475"
                     /db_xref="taxon:256374"
     gene            <1..>1302
                     /gene="matK"
     CDS             <1..>1302
                     /gene="matK"
                     /codon_start=1
                     /transl_table=11
                     /product="maturase K"
                     /protein_id="ACC99456.1"
                     /translation="IFYEPVEIFGYDNKSSLVLVKRLITRMYQQNFLISSVNDSNQKG
                     FWGHKHFFSSHFSSQMVSEGFGVILEIPFSSQLVSSLEEKKIPKYQNLRSIHSIFPFL
                     EDKFLHLNYVSDLLIPHPIHLEILVQILQCRIKDVPSLHLLRLLFHEYHNLNSLITSK
                     KFIYAFSKRKKRFLWLLYNSYVYECEYLFQFLRKQSSYLRSTSSGVFLERTHLYVKIE
                     HLLVVCCNSFQRILCFLKDPFMHYVRYQGKAILASKGTLILMKKWKFHLVNFWQSYFH
                     FWSQPYRIHIKQLSNYSFSFLGYFSSVLENHLVVRNQMLENSFIINLLTKKFDTIAPV
                     ISLIGSLSKAQFCTVLGHPISKPIWTDFSDSDILDRFCRICRNLCRYHSGSSKKQVLY
                     RIKYILRLSCARTLARKHKSTVRTFMRRLGSGLLEEFFMEEE"
ORIGIN      
        1 attttttacg aacctgtgga aatttttggt tatgacaata aatctagttt agtacttgtg
       61 aaacgtttaa ttactcgaat gtatcaacag aattttttga tttcttcggt taatgattct
      121 aaccaaaaag gattttgggg gcacaagcat tttttttctt ctcatttttc ttctcaaatg
      181 gtatcagaag gttttggagt cattctggaa attccattct cgtcgcaatt agtatcttct
      241 cttgaagaaa aaaaaatacc aaaatatcag aatttacgat ctattcattc aatatttccc
      301 tttttagaag acaaattttt acatttgaat tatgtgtcag atctactaat accccatccc
      361 atccatctgg aaatcttggt tcaaatcctt caatgccgga tcaaggatgt tccttctttg
      421 catttattgc gattgctttt ccacgaatat cataatttga atagtctcat tacttcaaag
      481 aaattcattt acgccttttc aaaaagaaag aaaagattcc tttggttact atataattct
      541 tatgtatatg aatgcgaata tctattccag tttcttcgta aacagtcttc ttatttacga
      601 tcaacatctt ctggagtctt tcttgagcga acacatttat atgtaaaaat agaacatctt
      661 ctagtagtgt gttgtaattc ttttcagagg atcctatgct ttctcaagga tcctttcatg
      721 cattatgttc gatatcaagg aaaagcaatt ctggcttcaa agggaactct tattctgatg
      781 aagaaatgga aatttcatct tgtgaatttt tggcaatctt attttcactt ttggtctcaa
      841 ccgtatagga ttcatataaa gcaattatcc aactattcct tctcttttct ggggtatttt
      901 tcaagtgtac tagaaaatca tttggtagta agaaatcaaa tgctagagaa ttcatttata
      961 ataaatcttc tgactaagaa attcgatacc atagccccag ttatttctct tattggatca
     1021 ttgtcgaaag ctcaattttg tactgtattg ggtcatccta ttagtaaacc gatctggacc
     1081 gatttctcgg attctgatat tcttgatcga ttttgccgga tatgtagaaa tctttgtcgt
     1141 tatcacagcg gatcctcaaa aaaacaggtt ttgtatcgta taaaatatat acttcgactt
     1201 tcgtgtgcta gaactttggc acggaaacat aaaagtacag tacgcacttt tatgcgaaga
     1261 ttaggttcgg gattattaga agaattcttt atggaagaag aa
//

上面我们指定的下载文件类型是Genbank文件,当然你也可以使用 rettype="fasta" 来获取Fasta格式的文件。

如果你要获取的文件格式是Bio.SeqIO所接受的格式, 你可以直接将其解析为一个SeqRecord :

>>> from Bio import SeqIO
>>> from Bio import Entrez
>>> handle = Entrez.efetch(db="nucleotide", id="EU490707", rettype="gb", retmode="text")
>>> record = SeqIO.read(handle, "genbank")
>>> handle.close()
>>> print(record.id)
EU490707.1
>>> print(record.name)
EU490707
>>> print(record.description)
Selenipedium aequinoctiale maturase K (matK) gene, partial cds; chloroplast
>>> print(len(record.features))
3
>>> print(repr(record.seq))
Seq('ATTTTTTACGAACCTGTGGAAATTTTTGGTTATGACAATAAATCTAGTTTAGTA...GAA', IUPACAmbiguousDNA())

但一般不推荐上面这个操作。推荐你先把序列数据保存到一个本地文件,然后使用Bio.SeqIO来解析。这样就不用每次都重复的下载同样的文件,减轻NCBI服务器的负载。例如:

>>> import os
>>> from Bio import SeqIO
>>> from Bio import Entrez
>>> Entrez.email = "××××××××××××××"
>>> filename = "EU490707.gbk"
>>> if not os.path.isfile(filename):
...     net_handle = Entrez.efetch(
...     db="nucleotide", id="EU490707", rettype="gb", retmode="text"
...     )
...     out_handle = open(filename, "w")
...     out_handle.write(net_handle.read())
...     out_handle.close()
...     net_handle.close()
...     print("Saved")
... 
4088
Saved
>>> print("Parsing...")
Parsing...
>>> record = SeqIO.read(filename, "genbank")
>>> print(record)
ID: EU490707.1
Name: EU490707
Description: Selenipedium aequinoctiale maturase K (matK) gene, partial cds; chloroplast
Number of features: 3
/molecule_type=DNA
/topology=linear
/data_file_division=PLN
/date=26-JUL-2016
/accessions=['EU490707']
/sequence_version=1
/keywords=['']
/source=chloroplast Selenipedium aequinoctiale
/organism=Selenipedium aequinoctiale
/taxonomy=['Eukaryota', 'Viridiplantae', 'Streptophyta', 'Embryophyta', 'Tracheophyta', 'Spermatophyta', 'Magnoliopsida', 'Liliopsida', 'Asparagales', 'Orchidaceae', 'Cypripedioideae', 'Selenipedium']
/references=[Reference(title='Phylogenetic utility of ycf1 in orchids: a plastid gene more variable than matK', ...), Reference(title='Direct Submission', ...)]
Seq('ATTTTTTACGAACCTGTGGAAATTTTTGGTTATGACAATAAATCTAGTTTAGTA...GAA', IUPACAmbiguousDNA())

NOTE:这里保存的是一个gbk为后缀的文件。文件存储在你的工作文件夹里。

那么如果你想得到一个xml输出的文件怎么办呢:

>>> from Bio import Entrez
>>> handle = Entrez.efetch(db="nucleotide", id="EU490707", retmode="xml")
>>> record = Entrez.read(handle)
>>> handle.close()
>>> record[0]["GBSeq_definition"]
'Selenipedium aequinoctiale maturase K (matK) gene, partial cds; chloroplast'
>>> record[0]["GBSeq_source"]
'chloroplast Selenipedium aequinoctiale'

以上就是下载基因序列的办法。

ELink: 在NCBI Entrez中搜索相关的条目

Biopython中Bio.Entrez.elink(),可以用来在NCBI Entrez数据库中寻找相关的条目。
举个例子说明:我们想使用ELink来从2009年的Bioinformatics杂志中寻找与Biopython应用相关的文章。这篇文章的PubMed ID 是19304878:

>>> from Bio import Entrez
>>> pmid = "19304878"
>>> record = Entrez.read(Entrez.elink(dbfrom="pubmed", id=pmid))
#变量 record 包含了一个Python列表,列出了已经搜索过的数据库。因为我们特指了一个PubMed ID来搜索,所以 record 只包含了一个条目。这个条目是一个字典变量,包含了我们需要寻找的条目的信息,以及能搜索到的所有相关的内容:
>>> record[0]["DbFrom"]
'pubmed'
>>> record[0]["IdList"]
['19304878']
#键"LinkSetDb"包含了搜索结果,将每个目标数据库保存为一个列表。在我们这个搜索中,我们只在PubMed数据库 中找到了结果
>>> len(record[0]["LinkSetDb"])
8
>>> for linksetdb in record[0]["LinkSetDb"]:
...     print(linksetdb["DbTo"], linksetdb["LinkName"], len(linksetdb["Link"]))
... 
pubmed pubmed_pubmed 281
pubmed pubmed_pubmed_alsoviewed 6
pubmed pubmed_pubmed_citedin 881
pubmed pubmed_pubmed_combined 6
pubmed pubmed_pubmed_five 6
pubmed pubmed_pubmed_refs 17
pubmed pubmed_pubmed_reviews 11
pubmed pubmed_pubmed_reviews_five 6
#实际的搜索结果被保存在键值为 "Link" 的字典下。在标准搜索下,总共找到了110个条目。让我们现在看看我们第一个搜索结果,应该就是我们搜索的文章ID:
>>> record[0]["LinkSetDb"][0]["Link"][0]
{'Id': '19304878'}
#第二个搜索结果:
>>> record[0]["LinkSetDb"][0]["Link"][1]
{'Id': '14630660'}
#通过一个循环来打印出所有的PubMed IDs:
>>> for link in record[0]["LinkSetDb"][0]["Link"]:
...     print(link["Id"])
... 
19304878
14630660
22909249
20739307
23023984
......

EGQuery: 全局搜索- 统计搜索的条目

EGQuery提供搜索字段在每个Entrez数据库中的数目。当我们只需要知道在每个数据库中能找到的条目的个数, 而不需要知道具体搜索结果的时候,这个工具就非常的有用。

>>> from Bio import Entrez
>>> handle = Entrez.egquery(term="biopython")
>>> record = Entrez.read(handle)
>>> for row in record["eGQueryResult"]:
...     print(row["DbName"], row["Count"])
... 
pubmed 28
pmc 1479
mesh 0
books 2
pubmedhealth 2
.........

ESpell: 拼写建议

ESpell可以检索拼写建议。举个例子:使用 Bio.Entrez.espell() 来获得Biopython正确的拼写:

>>> from Bio import Entrez
>>> handle = Entrez.espell(term="biopythooon")
>>> record = Entrez.read(handle)
>>> record["Query"]
'biopythooon'
>>> record["CorrectedQuery"]
'biopython'

解析大的Entrez XML文件

Entrez.read 函数将Entrez返回的结果读取到一个Python对象里面去,这个对象被保存在内存中。对于解析太大的XML文件而内存不够时,可以使用 Entrez.parse 这个函数。这是一个生成器函数,它将一个一个的读取XML文件里面的内容。只有XML 文件是一个列表对象的时候,这个函数才有用。

例如,你可以通过NCBI的FTP站点从Entrez Gene数据库中下载某个物种全部的条目作为一个文件。这个文件就会很大。比如:网站ftp://ftp.ncbi.nlm.nih.gov/gene/DATA/ASN_BINARY/Mammalia里包含了多个物种的ags.gz格式的序列文件,我们试着把人类的序列下载下来,文件大小是216116 KB。这个文件是 ASN 格式,可以通过NCBI的 gene2xml 程序转成XML格式。这里的代码参考:https://zhuanlan.zhihu.com/p/54609662。教材里的代码直接用是用不了的,它省略了很多步骤。

首先你需要先下载人类序列和解析工具:(以下代码要退出python再操作)

$ mkdir ncbi
$ cd ncbi
$ mkdir ags
$ mkdir tool
$ cd tool
$ wget ftp://ftp.ncbi.nlm.nih.gov/toolbox/ncbi_tools/converters/by_program/gene2xml/linux64.gene2xml.gz
$ gunzip linux64.gene2xml.gz
$ mv linux64.gene2xml gene2xml
$ cd ../ags
$ wget ftp://ftp.ncbi.nlm.nih.gov/gene/DATA/ASN_BINARY/Mammalia/Homo_sapiens.ags.gz
$ gunzip Homo_sapiens.ags.gz

都现在并且解压后,才可以操作教材里的那行代码:

#将下载的ags.gz文件转成xml文件
$ ../tool/gene2xml -b T -i Homo_sapiens.ags -o Homo_sapiens.xml
#这一步运行一段时间,因为解析后的xml文件是非常大的

运行后,你利用tree的命令应该会看到:

$ tree
.
├── ags
│   ├── Homo_sapiens.ags
│   └── Homo_sapiens.xml
└── tool
    └── gene2xml

然后进入python,进行解析:

>>> from Bio import Entrez
>>> handle = open("Homo_sapiens.xml")
>>> records = Entrez.parse(handle)
>>> for record in records:
...     status = record["Entrezgene_track-info"]["Gene-track"]["Gene-track_status"]
...     if status.attributes["value"]=="discontinued":
...             continue
...     geneid = record["Entrezgene_track-info"]["Gene-track"]["Gene-track_geneid"]
...     genename = record["Entrezgene_gene"]["Gene-ref"]["Gene-ref_locus"]
...     print(geneid, genename)
... 
1 A1BG
2 A2M
3 A2MP1
8 AA
9 NAT1
10 NAT2
11 NATP
12 SERPINA3
......

专用的解析器

现在讲一下如何下载相关文献。这里我总结了我在网上找到的相关代码进行了结合,没有报错并且有内容输出:

>>> from Bio import Entrez
>>> from Bio import Medline
>>> Entrez.email = "×××××××××××"
# 用 esearch 在 pubmed 库中搜索关键字为 "Head and Neck squamous cell carcinoma" 的文章
# RetMax 这个参数为每次返回的最大个数,因此如果把Count的值赋给RetMax就会获取全部的mouse的文章,这里为实例设置为100
>>> hnscc_esearch = Entrez.esearch(db="pubmed", term="Head and Neck squamous cell carcinoma", RetMax="100")
>>> read_esearch = Entrez.read(hnscc_esearch)
>>> idlist = read_esearch["IdList"]
>>> print ("Total: ", read_esearch["Count"])
Total:  36661
>>> print(idlist[0:40])
['32247987', '32247864', '32244899', '32244515', '32244173', '32244172', '32241209', '32239880', '32240908', '32240617', '32240499', '32239774', '32239313', '32239201', '32238472', '32238214', '32238162', '32238063', '32236893', '32236707', '32235493', '32234904', '32234899', '32234582', '32234410', '32231744', '32231567', '32229804', '32229486', '32228580', '32228488', '32227417', '32226833', '32226775', '32226773', '32224968', '32224897', '32224436', '32224315', '32223478']

用efetch下载:

#这里需要注意的是,下面id这个参数,最多只能30个,如果你不注意整了几百上千,是会报错的
>>> handle = Entrez.efetch(db="pubmed", id=idlist[0:29], rettype="medline", retmode="text")
#Medline解析:
>>> records = Medline.parse(handle)
>>> records = list(records)
#这里你要先在你的目的文件夹里建一个xls文件,用来一会儿保存下载的数据:
>>> with open("ref_paper/hnscc_pubmed.xls", "w") as file:
...     file.write("title\tauthors\tsource\tPubMed\n")
...     for record in records:
...             line = record.get("TI","?") + "\t" + str(record.get("AU","?")) + "\t" + str(record.get("SO", "?")) + "\t" + record.get("PMID","?") + "\n"
...             file.write(line)
...             print(i,line)
... 
28
249

然后可以看一下xls表里的内容:

上面可以看到一共输出了30篇文章,第一列是文章题目,第二列是作者,第三列是出处,也就是杂志,第四列是PubMed的ID号。

学习时一定要把代码亲自运行一遍,因为你永远不知道别人的代码在你的电脑上究竟是不是work的。

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

推荐阅读更多精彩内容