NCBI的

Deliverz(https://www.ncbi.nlm.nih.gov/Web/Search/entrezfs.html)是一个数据检索系统,为用户提供对NCBI数据库(例如PubMed、Gene、GEO等)的访问权限。您可以从网络浏览器访问Deliverz以手动输入查询,也可以使用Biopython的 Bio.Entrez 模块,用于以编程的方式访问Zeroz。后者允许您从Python脚本中搜索PubMed或下载GenBank记录。

Bio.Entrez 模块利用Deliverz编程实用程序(也称为EUtils),该实用程序由八个工具组成,NCBI的页面https://www.ncbi.nlm.nih.gov/books/NBK25501/上详细介绍了这些工具。这些工具中的每一个都对应于中的一个Python函数 Bio.Entrez 模块,如下所述。该模块确保查询使用正确的URL,并且遵循NCBI负责任的数据访问指南。

Deliverz编程实用程序返回的输出通常为ML格式。要解析此类输出,您有几个选项:

  1. 使用 Bio.Entrez 的解析器,用于将HTML输出解析为Python对象;

  2. 使用Python标准库中可用的一种ML解析器;

  3. 将该文档输出作为原始文本读取,并通过字符串搜索和操作对其进行解析。

请参阅Python文档,了解Python标准库中的ML解析器的描述。在这里,我们讨论Biopython中的解析器 Bio.Entrez module.此解析器可用于解析通过提供的数据 Bio.Entrez 对Deliverz的编程访问功能,但也可用于解析来自NCBI Deliverz的存储在文件中的文档数据。在后一种情况下,应该以二进制模式打开HTML文件(例如 open("myfile.xml", "rb") )中的ML解析器 Bio.Entrez 正确工作。或者,您可以将文件名或路径传递给XML文件,并让 Bio.Entrez 负责打开和关闭文件。

NCBI使用DART(文档类型定义)文件来描述包含在ML文件中的信息的结构。NCBI使用的大部分td文件都包含在Biopython发行版中。的 Bio.Entrez 解析器在解析由NCBI P2P z返回的XML文件时使用DTD文件。

有时,您可能会发现Biopython发行版中缺少与特定的ML文件关联的td文件。特别是,当NCBI更新其DART文件时可能会发生这种情况。如果发生这种情况, Entrez.read 将显示一条警告消息,其中包含丢失的DART文件的名称和URL。解析器将继续通过互联网访问丢失的td文件,从而允许继续解析该文档。然而,如果DART文件在本地可用,解析器的速度要快得多。为此,请从警告消息中的URL下载DART文件并将其放入目录中 ...site-packages/Bio/Entrez/DTDs ,包含其他DTD文件。如果您对此目录没有写入权限,也可以将DTD文件放在 ~/.biopython/Bio/Entrez/DTDs ,在哪里 ~ 代表您的主目录。由于该目录在目录之前读取 ...site-packages/Bio/Entrez/DTDs ,您还可以将较新版本的td文件放在那里,如果 ...site-packages/Bio/Entrez/DTDs 变得过时。或者,如果您从源代码安装Biopython,则可以将DART文件添加到源代码中 Bio/Entrez/DTDs 目录,并重新安装Biopython。这会将新的td文件与其他td文件一起安装在正确的位置。

Deliverz编程实用程序还可以生成其他格式的输出,例如用于序列数据库的Fasta或ESB文件格式,或用于文献数据库的MedLine格式,如第节中讨论的  专业解析器 .

中的函数 Bio.Entrez 用于对二进制格式或文本格式的Deliverz返回数据进行编程访问,具体取决于请求的数据类型。在大多数情况下,这些函数在编码为UTF-8的假设下,通过将从NCBI z获得的数据解码为Python字符串,以文本格式返回数据。然而,HTML数据以二进制格式返回。原因是编码是在HTML文档本身中指定的,这意味着在开始解析文件之前我们不会知道要使用的正确编码。 Bio.Entrez 因此,解析器接受二进制格式的数据,从ML中提取编码,并使用它将ML文档中的所有文本解码为Python字符串,确保所有文本(特别是英语以外的语言)得到正确解释。这也是为什么当您想要使用时应该以二进制模式打开一个文档的原因 Bio.Entrez 的解析器来解析该文件。

埃斯珀兹准则

在使用Biopython访问NCBI的在线资源之前(通过 Bio.Entrez or some of the other modules), please read the NCBI’s Entrez User Requirements .如果NCBI发现您滥用他们的系统,他们可以并且将会禁止您访问!

解释一下:

  • 对于任何超过100个的请求系列,请在周末或美国高峰时段以外的时间执行此操作。这取决于你要遵守。

  • 使用https://eutils.ncbi.nlm.nih.gov地址,而不是标准的NCBI网址。Biopython使用此网址。

  • 如果您使用API密钥,则每秒最多可以进行10个查询,否则每秒最多3个查询。这由Biopython自动强制执行。包括 api_key="MyAPIkey" 在参数列表中或将其设置为模块级变量:

    >>> from Bio import Entrez
    >>> Entrez.api_key = "MyAPIkey"
    
  • 使用可选的电子邮件参数,以便NCBI可以在出现问题时与您联系。您可以在每次调用Deliverz时显式地将其设置为参数(例如包含 email="A.N.Other@example.com" 在参数列表中),或者您可以设置全球电子邮件地址:

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

    Bio.Entrez 然后,每次致电Zuz时都会使用此电子邮件地址。的 example.com 地址是专门用于文档的保留域名(RFC 2606)。请不要使用随机的电子邮件-最好根本不发送电子邮件。自2010年6月1日起,电子邮件参数一直是强制性的。如果过度使用,NCBI将尝试通过阻止访问电子实用程序之前提供的电子邮件地址联系用户。

  • 如果您在某个更大的软件套件中使用Biopython,请使用工具参数来指定此内容。您可以在每次调用Deliverz时显式地将工具名称设置为参数(例如包括 tool="MyLocalScript" 在参数列表中),或者您可以设置全局工具名称:

    >>> from Bio import Entrez
    >>> Entrez.tool = "MyLocalScript"
    

    工具参数将默认为Biopython。

  • 对于大型查询,NCBI还建议使用其会话历史记录功能(WebEnv会话cookie字符串,请参见第  使用历史记录和WebEnv ).这只是稍微复杂一点。

总之,对您的使用水平保持明智。如果您计划下载大量数据,请考虑其他选项。例如,如果您希望轻松访问所有人类基因,请考虑通过Photoshop将每个染色体作为基因库文件获取,并将其导入您自己的BioSQL数据库(请参阅部分  BioSQL -在关系数据库中存储序列 ).

EInfo:获取有关Deliverz数据库的信息

EInfo为每个NCBI数据库提供字段索引术语计数、上次更新和可用链接。此外,您还可以使用EInfo获取可通过Deliverz实用程序访问的所有数据库名称的列表:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.einfo()
>>> result = stream.read()
>>> stream.close()

可变 result 现在包含一个可扩展的数据库列表:

>>> print(result)
<?xml version="1.0"?>
<!DOCTYPE eInfoResult PUBLIC "-//NLM//DTD eInfoResult, 11 May 2002//EN"
 "https://www.ncbi.nlm.nih.gov/entrez/query/DTD/eInfo_020511.dtd">
<eInfoResult>
<DbList>
        <DbName>pubmed</DbName>
        <DbName>protein</DbName>
        <DbName>nucleotide</DbName>
        <DbName>nuccore</DbName>
        <DbName>nucgss</DbName>
        <DbName>nucest</DbName>
        <DbName>structure</DbName>
        <DbName>genome</DbName>
        <DbName>books</DbName>
        <DbName>cancerchromosomes</DbName>
        <DbName>cdd</DbName>
        <DbName>gap</DbName>
        <DbName>domains</DbName>
        <DbName>gene</DbName>
        <DbName>genomeprj</DbName>
        <DbName>gensat</DbName>
        <DbName>geo</DbName>
        <DbName>gds</DbName>
        <DbName>homologene</DbName>
        <DbName>journals</DbName>
        <DbName>mesh</DbName>
        <DbName>ncbisearch</DbName>
        <DbName>nlmcatalog</DbName>
        <DbName>omia</DbName>
        <DbName>omim</DbName>
        <DbName>pmc</DbName>
        <DbName>popset</DbName>
        <DbName>probe</DbName>
        <DbName>proteinclusters</DbName>
        <DbName>pcassay</DbName>
        <DbName>pccompound</DbName>
        <DbName>pcsubstance</DbName>
        <DbName>snp</DbName>
        <DbName>taxonomy</DbName>
        <DbName>toolkit</DbName>
        <DbName>unigene</DbName>
        <DbName>unists</DbName>
</DbList>
</eInfoResult>

由于这是一个相当简单的HTML文件,因此我们可以简单地通过字符串搜索来提取它包含的信息。使用 Bio.Entrez 相反,我们可以直接将这个HTML文件解析为Python对象:

>>> from Bio import Entrez
>>> stream = Entrez.einfo()
>>> record = Entrez.read(stream)

现在 record 是一本只有一个关键字的字典:

>>> record.keys()
dict_keys(['DbList'])

此键中存储的值是上面的HTML中显示的数据库名称列表:

>>> record["DbList"]
['pubmed', 'protein', 'nucleotide', 'nuccore', 'nucgss', 'nucest',
 'structure', 'genome', 'books', 'cancerchromosomes', 'cdd', 'gap',
 'domains', 'gene', 'genomeprj', 'gensat', 'geo', 'gds', 'homologene',
 'journals', 'mesh', 'ncbisearch', 'nlmcatalog', 'omia', 'omim', 'pmc',
 'popset', 'probe', 'proteinclusters', 'pcassay', 'pccompound',
 'pcsubstance', 'snp', 'taxonomy', 'toolkit', 'unigene', 'unists']

对于这些数据库中的每个数据库,我们可以再次使用EInfo来获取更多信息:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.einfo(db="pubmed")
>>> record = Entrez.read(stream)
>>> record["DbInfo"]["Description"]
'PubMed bibliographic record'
>>> record["DbInfo"]["Count"]
'17989604'
>>> record["DbInfo"]["LastUpdate"]
'2008/05/24 06:45'

尝试 record["DbInfo"].keys() 以获取此记录中存储的其他信息。最有用的一个是可与ESSEARCH一起使用的可能搜索字段列表:

>>> 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] 仅限于桑格中心的作者。这可能非常方便--尤其是如果您对特定数据库不太熟悉的话。

ESSEARCH:搜索SEARCH数据库

要搜索任何这些数据库,我们使用 Bio.Entrez.esearch() .例如,让我们在PubMed中搜索标题中包含Biopython的出版物:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esearch(db="pubmed", term="biopython[title]", retmax="40")
>>> record = Entrez.read(stream)
>>> "19304878" in record["IdList"]
True
>>> print(record["IdList"])
['22909249', '19304878']

在此输出中,您将看到PubMed ID(包括19304878,这是Biopython应用笔记的PMID),可以由EFetch检索(请参阅部分 EFetch:从Deliverz下载完整记录 ).

您还可以使用ESSEARCH搜索SEN。在这里我们将快速搜索 matK 基因 Cypripedioideae 兰花(见第  EInfo:获取有关Deliverz数据库的信息 关于EInfo,了解可以在每个Deliverz数据库中搜索哪些字段的一种方法):

>>> stream = Entrez.esearch(
...     db="nucleotide", term="Cypripedioideae[Orgn] AND matK[Gene]", idtype="acc"
... )
>>> record = Entrez.read(stream)
>>> record["Count"]
'348'
>>> record["IdList"]
['JQ660909.1', 'JQ660908.1', 'JQ660907.1', 'JQ660906.1', ..., 'JQ660890.1']

每个ID(JQ660909.1、JQ660908.1、JQ660907.1、..)都是一个基因库标识符(登录号)。见章节  EFetch:从Deliverz下载完整记录 了解有关如何实际下载这些基因库记录的信息。

请注意,而不是像这样的物种名称 Cypripedioideae[Orgn] ,您可以使用NCBI分类单元标识符限制搜索,这里是 txid158330[Orgn] . ESSEARCH帮助页面上目前没有记录这一点-NCBI在回复电子邮件查询时解释了这一点。您通常可以通过使用Deliverz Web界面来推断搜索项格式。例如包括 complete[prop] 基因组搜索仅限于完成的基因组。

作为最后一个例子,让我们获取计算期刊标题列表:

>>> stream = Entrez.esearch(db="nlmcatalog", term="computational[Journal]", retmax="20")
>>> record = Entrez.read(stream)
>>> print("{} computational journals found".format(record["Count"]))
117 computational Journals found
>>> print("The first 20 are\n{}".format(record["IdList"]))
['101660833', '101664671', '101661657', '101659814', '101657941',
 '101653734', '101669877', '101649614', '101647835', '101639023',
 '101627224', '101647801', '101589678', '101585369', '101645372',
 '101586429', '101582229', '101574747', '101564639', '101671907']

同样,我们可以使用EFetch来获取每个期刊ID的更多信息。

ESSEARCH有许多有用的选项-请参阅 ESearch help page for more information.

EPost:重传标识符列表

EPost上传UI列表以供后续搜索策略使用;请参阅 EPost help page for more information.它可以通过Biopython通过 Bio.Entrez.epost() 功能

为了举例说明这何时有用,假设您有一长串想要使用EFetch下载的ID(可能是序列,可能是引用--任何内容)。当您使用EFetch发出请求时,您的ID列表、数据库等都将变成发送到服务器的长URL。如果您的ID列表很长,该URL就会变得很长,并且长URL可能会中断(例如,一些代理无法很好地处理)。

相反,您可以将其分为两个步骤,首先使用EPost上传ID列表(这在内部使用“HTML帖子”,而不是“HTML获取”,以解决长URL问题)。通过历史记录支持,您可以参考这一长串ID,并使用EFetch下载相关数据。

让我们看一个简单的例子来了解EPost的工作原理-上传一些PubMed标识符:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> id_list = ["19304878", "18606172", "16403221", "16377612", "14871861", "14630660"]
>>> print(Entrez.epost("pubmed", id=",".join(id_list)).read())
<?xml version="1.0"?>
<!DOCTYPE ePostResult PUBLIC "-//NLM//DTD ePostResult, 11 May 2002//EN"
 "https://www.ncbi.nlm.nih.gov/entrez/query/DTD/ePost_020511.dtd">
<ePostResult>
    <QueryKey>1</QueryKey>
    <WebEnv>NCID_01_206841095_130.14.22.101_9001_1242061629</WebEnv>
</ePostResult>

返回的ML包括两个重要的字符串, QueryKeyWebEnv 它们共同定义了您的历史课程。您可以提取这些值以供另一个Deliverz调用(例如EFetch)使用:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> id_list = ["19304878", "18606172", "16403221", "16377612", "14871861", "14630660"]
>>> search_results = Entrez.read(Entrez.epost("pubmed", id=",".join(id_list)))
>>> webenv = search_results["WebEnv"]
>>> query_key = search_results["QueryKey"]

部分  使用历史记录和WebEnv 展示如何使用历史记录功能。

概要:从主要ID检索摘要

Esummary从主要ID列表中检索文档摘要(请参阅 ESummary help page 了解更多信息)。在Biopython中,Esummary的名称为 Bio.Entrez.esummary() .例如,使用上面的搜索结果,我们可以找到有关ID 30367期刊的更多信息:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esummary(db="nlmcatalog", id="101660833")
>>> record = Entrez.read(stream)
>>> 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:从Deliverz下载完整记录

EFetch是您想要从Deliverz检索完整记录时使用的工具。这涵盖了几个可能的数据库,如主要部分所述 EFetch Help page .

对于大多数数据库,NCBI支持几种不同的文件格式。使用以下命令从Xplatz请求特定的文件格式 Bio.Entrez.efetch() requires specifying the rettype and/or retmode optional arguments. The different combinations are described for each database type on the pages linked to on NCBI efetch webpage .

一种常见的用途是下载FASTA或SEN/GenPept纯文本格式的序列(然后可以用 Bio.SeqIO ,请参阅部分  从网上解析基因库记录 和  EFetch:从Deliverz下载完整记录 ).从 Cypripedioideae 上面的例子,我们可以使用下载SEN记录EU490707 Bio.Entrez.efetch :

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.efetch(db="nucleotide", id="EU490707", rettype="gb", retmode="text")
>>> print(stream.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
//

请注意,自2016年10月起,GI标识符将停止使用,转而使用登录号。您仍然可以根据序列GI获取序列,但新序列不再被赋予此标识符。您应该按照示例中所做的那样通过“访问号”来引用它们。

的论点 rettype="gb"retmode="text" 让我们以基因库格式下载此记录。

请注意,直到2009年复活节,Deliverz EFetch API允许您使用“genbank”作为返回类型,但NCBI现在坚持使用官方返回类型“gi”或“Gbwithpiece”(或蛋白质的“GP”),正如在线所述。另请注意,在2012年2月之前,Deliverz EFetch API默认返回纯文本文件,但现在默认返回是ML。

或者,您可以例如使用 rettype="fasta" to get the Fasta-format; see the EFetch Sequences Help page 对于其他选择。请记住-可用的格式取决于您从哪个数据库下载-请参阅主要 EFetch Help page .

如果您以接受的格式之一获取记录 Bio.SeqIO (see章  序列输入/输出 ),您可以直接将其解析为 SeqRecord :

>>> from Bio import SeqIO
>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.efetch(db="nucleotide", id="EU490707", rettype="gb", retmode="text")
>>> record = SeqIO.read(stream, "genbank")
>>> stream.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
>>> record.seq
Seq('ATTTTTTACGAACCTGTGGAAATTTTTGGTTATGACAATAAATCTAGTTTAGTA...GAA')

请注意,更典型的用法是将序列数据保存到本地文件中, then 解析它 Bio.SeqIO .这可以让您不必在处理脚本时重复重新下载相同的文件,并减轻NCBI服务器的负载。例如:

import os
from Bio import SeqIO
from Bio import Entrez

Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
filename = "EU490707.gbk"
if not os.path.isfile(filename):
    # Downloading...
    stream = Entrez.efetch(db="nucleotide", id="EU490707", rettype="gb", retmode="text")
    output = open(filename, "w")
    output.write(streame.read())
    output.close()
    stream.close()
    print("Saved")

print("Parsing...")
record = SeqIO.read(filename, "genbank")
print(record)

要获取HTML格式的输出,您可以使用 Bio.Entrez.read() 功能、使用 retmode="xml" :

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.efetch(db="nucleotide", id="EU490707", retmode="xml")
>>> record = Entrez.read(stream)
>>> stream.close()
>>> record[0]["GBSeq_definition"]
'Selenipedium aequinoctiale maturase K (matK) gene, partial cds; chloroplast'
>>> record[0]["GBSeq_source"]
'chloroplast Selenipedium aequinoctiale'

所以,这涉及序列。有关解析特定于其他数据库的文件格式的示例(例如 MEDLINE PubMed中使用的格式),请参阅部分  专业解析器 .

如果您想使用执行搜索 Bio.Entrez.esearch() ,然后下载记录 Bio.Entrez.efetch() ,您应该使用WebEnv历史记录功能-请参阅部分  使用历史记录和WebEnv .

EGQuery:全局查询-搜索项计数

EGQuery为每个Deliverz数据库中的搜索项提供计数(即全局查询)。这对于了解您的搜索词在每个数据库中会找到多少项而无需实际使用ESSEARCH执行大量单独搜索(请参阅中的示例 搜索、下载和解析Deliverz核苷记录 下面)。

本示例中使用了 Bio.Entrez.egquery() 要获取“Biopython”的计数:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.egquery(term="biopython")
>>> record = Entrez.read(stream)
>>> for row in record["eGQueryResult"]:
...     print(row["DbName"], row["Count"])
...
pubmed 6
pmc 62
journals 0
...

看到 EGQuery help page for more information.

ESpell:获取拼写建议

ESpell检索拼写建议。本示例中使用了 Bio.Entrez.espell() 获取Biopython的正确拼写:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.espell(term="biopythooon")
>>> record = Entrez.read(stream)
>>> record["Query"]
'biopythooon'
>>> record["CorrectedQuery"]
'biopython'

看到 ESpell help page for more information.它的主要用途是让图形用户界面工具为搜索项提供自动建议。

解析巨大的Deliverz HTML文件

Entrez.read 函数将Inbox返回的整个ML文件读取到单个Python对象中,该对象保存在内存中。要分析太大而无法容纳内存的Deliverz ML文件,可以使用该函数 Entrez.parse .这是一个生成器函数,用于逐个读取ML文件中的记录。此函数仅在HTML文件反映Python列表对象时才有用(换句话说,如果 Entrez.read 在具有无限内存资源的计算机上将返回Python列表)。

例如,您可以从NCBI的https网站以文件形式下载特定生物体的整个Inbox Gene数据库。这些文件可能非常大。例如,2009年9月4日,该文件 Homo_sapiens.ags.gz ,包含人类Inbox Gene数据库,大小为116576 kB。该文件位于 ASN 格式,可以转换成XML文件使用NCBI的 gene2xml 程序(请参阅NCBI的ftp网站了解更多信息):

$ gene2xml -b T -i Homo_sapiens.ags -o Homo_sapiens.xml

生成的ML文件的大小为6.1 GB。试图 Entrez.read 在此文件上将导致 MemoryError 在许多计算机上。

XML文件 Homo_sapiens.xml 由一系列Deliverz基因记录组成,每条记录对应于人类的一个Deliverz基因。 Entrez.parse 一一检索这些基因记录。然后,您可以通过迭代记录来打印或将相关信息存储在每条记录中。例如,此脚本迭代Inbox基因记录并打印出所有当前基因的基因编号和名称:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = open("Homo_sapiens.xml", "rb")
>>> records = Entrez.parse(stream)

也可以使用

>>> records = Entrez.parse("Homo_sapiens.xml")

并让 Bio.Entrez 负责打开和关闭文件。这更安全,因为文件在解析后或发生错误时将自动关闭。

>>> 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 A2MP
8 AA
9 NAT1
10 NAT2
11 AACP
12 SERPINA3
13 AADAC
14 AAMP
15 AANAT
16 AARS
17 AAVS1
...

HTML换码字符

已发布的记录可能包含HTML标签,以指示例如脚注、大写或粗体文本,以及通过MathML的数学符号。默认情况下 Bio.Entrez 解析器将所有文本视为没有标记的纯文本;例如,Pubmed记录的抽象片段“:math:''”,其编码为

<i>P</i> &lt; 0.05

在Deliverz返回的文档中,转换为Python字符串

'<i>P</i> < 0.05'

Bio.Entrez 解析器。虽然这更易于人类阅读,但由于小于符号,它不是有效的HTML,并且使得例如通过HTML解析器对文本的进一步处理不切实际。要确保解析器返回的所有字符串都是有效的HTML,请调用 Entrez.readEntrez.parseescape 参数设置为 True :

>>> record = Entrez.read(stream, escape=True)

然后,解析器将用HTML-escaped的等效字符替换HTML中不允许的所有字符;在上面的例子中,解析器将生成

'<i>P</i> &lt; 0.05'

这是一个有效的HTML片段。默认情况下, escapeFalse .

处理错误

该文件不是ML文件

例如,如果您尝试将Fasta文件视为一个HTML文件,就会出现此错误:

>>> from Bio import Entrez
>>> stream = open("NC_005816.fna", "rb")  # a Fasta file
>>> record = Entrez.read(stream)
Traceback (most recent call last):
  ...
Bio.Entrez.Parser.NotXMLError: Failed to parse the XML data (syntax error: line 1, column 0). Please make sure that the input data are in XML format.

在这里,解析器没有找到 <?xml ... 标记,该标记应该用来开始一个标记,因此(正确地)确定该文件不是一个ML文件。

文件过早结束或已损坏

当您的文件为ML格式但已损坏(例如,提前结束)时,解析器将引发CorruptedMQLErsor。

以下是过早结束的HTML文件的示例:

<?xml version="1.0"?>
<!DOCTYPE eInfoResult PUBLIC "-//NLM//DTD eInfoResult, 11 May 2002//EN" "https://www.ncbi.nlm.nih.gov/entrez/query/DTD/eInfo_020511.dtd">
<eInfoResult>
<DbList>
        <DbName>pubmed</DbName>
        <DbName>protein</DbName>
        <DbName>nucleotide</DbName>
        <DbName>nuccore</DbName>
        <DbName>nucgss</DbName>
        <DbName>nucest</DbName>
        <DbName>structure</DbName>
        <DbName>genome</DbName>
        <DbName>books</DbName>
        <DbName>cancerchromosomes</DbName>
        <DbName>cdd</DbName>

这将生成以下回溯:

>>> Entrez.read(stream)
Traceback (most recent call last):
  ...
Bio.Entrez.Parser.CorruptedXMLError: Failed to parse the XML data (no element found: line 16, column 0). Please make sure that the input data are not corrupted.

请注意,错误消息告诉您在ML文件中的哪个点检测到错误。

该文件包含关联DART中缺失的项

这是一个包含在相应DART文件中没有描述的标记的ML文件示例:

<?xml version="1.0"?>
<!DOCTYPE eInfoResult PUBLIC "-//NLM//DTD eInfoResult, 11 May 2002//EN" "https://www.ncbi.nlm.nih.gov/entrez/query/DTD/eInfo_020511.dtd">
<eInfoResult>
        <DbInfo>
        <DbName>pubmed</DbName>
        <MenuName>PubMed</MenuName>
        <Description>PubMed bibliographic record</Description>
        <Count>20161961</Count>
        <LastUpdate>2010/09/10 04:52</LastUpdate>
        <FieldList>
                <Field>
...
                </Field>
        </FieldList>
        <DocsumList>
                <Docsum>
                        <DsName>PubDate</DsName>
                        <DsType>4</DsType>
                        <DsTypeName>string</DsTypeName>
                </Docsum>
                <Docsum>
                        <DsName>EPubDate</DsName>
...
        </DbInfo>
</eInfoResult>

在这个文件中,由于某种原因, <DocsumList> (and其他几个)没有在DART文件中列出 eInfo_020511.dtd ,它在第二行指定为该XML文件的DTD。默认情况下,如果解析器在DTD中找不到某个标记,它将停止并引发ValidationError:

>>> from Bio import Entrez
>>> stream = open("einfo3.xml", "rb")
>>> record = Entrez.read(stream)
Traceback (most recent call last):
  ...
Bio.Entrez.Parser.ValidationError: Failed to find tag 'DocsumList' in the DTD. To skip all tags that are not represented in the DTD, please call Bio.Entrez.read or Bio.Entrez.parse with validate=False.

或者,您可以指示解析器跳过此类标签,而不是引发验证错误。这是通过调用来完成的 Entrez.readEntrez.parse 与参数 validate 等于假:

>>> from Bio import Entrez
>>> stream = open("einfo3.xml", "rb")
>>> record = Entrez.read(stream, validate=False)
>>> stream.close()

当然,MTD中不包含的文档中的文档信息不会出现在 Entrez.read .

该文件包含错误消息

例如,当您尝试访问不存在的PubMed ID的PubMed记录时,可能会发生这种情况。默认情况下,这将引发 RuntimeError :

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esummary(db="pubmed", id="99999999")
>>> record = Entrez.read(stream)
Traceback (most recent call last):
...
RuntimeError: UID=99999999: cannot get document summary

如果您正在访问多个PubMed记录, RuntimeError 如果其中一个PubMed ID不正确,将阻止您接收任何PubMed记录的结果。为了避免此问题,您可以设置 ignore_errors 论点 True .这将返回有效PubMed ID的请求结果,以及 ErrorElement 对于不正确的ID:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esummary(db="pubmed", id="19304878,99999999,31278684")
>>> record = Entrez.read(stream, ignore_errors=True)
>>> len(record)
3
>>> record[0].tag
'DocSum'
>>> record[0]["Title"]
'Biopython: freely available Python tools for computational molecular biology and bioinformatics.'
>>> record[1].tag
'ERROR'
>>> record[1]
ErrorElement('UID=99999999: cannot get document summary')
>>> record[2].tag
'DocSum'
>>> record[2]["Title"]
'Sharing Programming Resources Between Bio* Projects.'

专业解析器

Bio.Entrez.read() 函数可以解析Deliverz返回的大部分(如果不是全部的话)ML输出。Deliverz通常允许您检索其他格式的记录,这与ML格式相比在可读性(或下载大小)方面可能具有一些优势。

要使用以下方式从Deliverz请求特定的文件格式 Bio.Entrez.efetch() requires specifying the rettype and/or retmode optional arguments. The different combinations are described for each database type on the NCBI efetch webpage .

一个明显的情况是,您可能更喜欢下载FASTA或SEN/GenPept纯文本格式的序列(然后可以用 Bio.SeqIO ,请参阅部分  从网上解析基因库记录 和  EFetch:从Deliverz下载完整记录 ).对于文献数据库,Biopython包含一个用于 MEDLINE PubMed中使用的格式。

解析Medline记录

您可以在中找到Medline解析器 Bio.Medline .假设我们要解析该文件 pubmed_result1.txt ,包含一张Medline记录。您可以在Biopython的 Tests\Medline 目录.该文件看起来像这样:

PMID- 12230038
OWN - NLM
STAT- MEDLINE
DA  - 20020916
DCOM- 20030606
LR  - 20041117
PUBM- Print
IS  - 1467-5463 (Print)
VI  - 3
IP  - 3
DP  - 2002 Sep
TI  - The Bio* toolkits--a brief overview.
PG  - 296-302
AB  - Bioinformatics research is often difficult to do with commercial software. The
      Open Source BioPerl, BioPython and Biojava projects provide toolkits with
...

我们首先打开文件,然后解析它:

>>> from Bio import Medline
>>> with open("pubmed_result1.txt") as stream:
...     record = Medline.read(stream)
...

record 现在包含Medline记录作为Python词典:

>>> record["PMID"]
'12230038'
>>> record["AB"]
'Bioinformatics research is often difficult to do with commercial software.
The Open Source BioPerl, BioPython and Biojava projects provide toolkits with
multiple functionality that make it easier to create customized pipelines or
analysis. This review briefly compares the quirks of the underlying languages
and the functionality, documentation, utility and relative advantages of the
Bio counterparts, particularly from the point of view of the beginning
biologist programmer.'

Medline记录中使用的关键名称可能相当晦涩;使用

>>> help(record)

作一个简短的总结。

要解析包含多个Medline记录的文件,您可以使用 parse 功能相反:

>>> from Bio import Medline
>>> with open("pubmed_result2.txt") as stream:
...     for record in Medline.parse(stream):
...         print(record["TI"])
...
A high level interface to SCOP and ASTRAL implemented in python.
GenomeDiagram: a python package for the visualization of large-scale genomic data.
Open source clustering software.
PDB file parser and structure class implemented in Python.

您还可以解析通过文件下载的Medline记录,而不是解析存储在文件中的Medline记录 Bio.Entrez.efetch .例如,让我们看看PubMed中与Biopython相关的所有Medline记录:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esearch(db="pubmed", term="biopython")
>>> record = Entrez.read(stream)
>>> record["IdList"]
['19304878', '18606172', '16403221', '16377612', '14871861', '14630660', '12230038']

我们现在使用 Bio.Entrez.efetch 要下载这些Medline记录:

>>> idlist = record["IdList"]
>>> stream = Entrez.efetch(db="pubmed", id=idlist, rettype="medline", retmode="text")

在这里,我们指定 rettype="medline", retmode="text" 以获取纯文本Medline格式的Medline记录。现在我们用 Bio.Medline 要解析这些记录:

>>> from Bio import Medline
>>> records = Medline.parse(stream)
>>> for record in records:
...     print(record["AU"])
...
['Cock PJ', 'Antao T', 'Chang JT', 'Chapman BA', 'Cox CJ', 'Dalke A', ..., 'de Hoon MJ']
['Munteanu CR', 'Gonzalez-Diaz H', 'Magalhaes AL']
['Casbon JA', 'Crooks GE', 'Saqi MA']
['Pritchard L', 'White JA', 'Birch PR', 'Toth IK']
['de Hoon MJ', 'Imoto S', 'Nolan J', 'Miyano S']
['Hamelryck T', 'Manderick B']
['Mangalam H']

为了进行比较,这里我们展示了一个使用XML格式的示例:

>>> stream = Entrez.efetch(db="pubmed", id=idlist, rettype="medline", retmode="xml")
>>> records = Entrez.read(stream)
>>> for record in records["PubmedArticle"]:
...     print(record["MedlineCitation"]["Article"]["ArticleTitle"])
...
Biopython: freely available Python tools for computational molecular biology and
 bioinformatics.
Enzymes/non-enzymes classification model complexity based on composition, sequence,
 3D and topological indices.
A high level interface to SCOP and ASTRAL implemented in python.
GenomeDiagram: a python package for the visualization of large-scale genomic data.
Open source clustering software.
PDB file parser and structure class implemented in Python.
The Bio* toolkits--a brief overview.

请注意,在这两个例子中,为了简单起见,我们天真地组合了ESEARCH和EFetch。在这种情况下,NCBI希望您使用他们的历史功能,如第节所示  使用历史记录和WebEnv .

分析GEO记录

GEO (Gene Expression Omnibus _)是高通量基因表达和杂交阵列数据的数据库。的 Bio.Geo 模块可用于解析GEO格式的数据。

下面的代码片段显示如何解析示例GEO文件 GSE16.txt 创建记录并打印记录:

>>> from Bio import Geo
>>> stream = open("GSE16.txt")
>>> records = Geo.parse(stream)
>>> for record in records:
...     print(record)
...

您可以使用ESSEARCH搜索“gds”数据库(GEO数据集):

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esearch(db="gds", term="GSE16")
>>> record = Entrez.read(stream)
>>> stream.close()
>>> record["Count"]
'27'
>>> record["IdList"]
['200000016', '100000028', ...]

从Zeroz网站,UID“200000016”是GDS16,而另一个命中“100000028”是相关的平台,GPL 28。不幸的是,在撰写本文时,NCBI似乎不支持使用XML下载GEO文件(不是XML,也不是 Simple Omnibus Format in Text (SOFT)格式)。

然而,实际上可以直接从ftp://ftp.ncbi.nih.gov/pub/geo/通过HTTPS下载GEO文件。在这种情况下,您可能需要ftp://ftp.ncbi.nih.gov/pub/geo/DATA/SOFT/by_series/GSE16/GSE16_family.soft.gz(一个压缩文件,请参阅Python模块gZip)。

解析UniGene记录

UniGene是NCBI的转录组数据库,每条UniGene记录都显示了与特定生物体中特定基因相关的一组转录本。典型的UniGene记录如下:

ID          Hs.2
TITLE       N-acetyltransferase 2 (arylamine N-acetyltransferase)
GENE        NAT2
CYTOBAND    8p22
GENE_ID     10
LOCUSLINK   10
HOMOL       YES
EXPRESS      bone| connective tissue| intestine| liver| liver tumor| normal| soft tissue/muscle tissue tumor| adult
RESTR_EXPR   adult
CHROMOSOME  8
STS         ACC=PMC310725P3 UNISTS=272646
STS         ACC=WIAF-2120 UNISTS=44576
STS         ACC=G59899 UNISTS=137181
...
STS         ACC=GDB:187676 UNISTS=155563
PROTSIM     ORG=10090; PROTGI=6754794; PROTID=NP_035004.1; PCT=76.55; ALN=288
PROTSIM     ORG=9796; PROTGI=149742490; PROTID=XP_001487907.1; PCT=79.66; ALN=288
PROTSIM     ORG=9986; PROTGI=126722851; PROTID=NP_001075655.1; PCT=76.90; ALN=288
...
PROTSIM     ORG=9598; PROTGI=114619004; PROTID=XP_519631.2; PCT=98.28; ALN=288

SCOUNT      38
SEQUENCE    ACC=BC067218.1; NID=g45501306; PID=g45501307; SEQTYPE=mRNA
SEQUENCE    ACC=NM_000015.2; NID=g116295259; PID=g116295260; SEQTYPE=mRNA
SEQUENCE    ACC=D90042.1; NID=g219415; PID=g219416; SEQTYPE=mRNA
SEQUENCE    ACC=D90040.1; NID=g219411; PID=g219412; SEQTYPE=mRNA
SEQUENCE    ACC=BC015878.1; NID=g16198419; PID=g16198420; SEQTYPE=mRNA
SEQUENCE    ACC=CR407631.1; NID=g47115198; PID=g47115199; SEQTYPE=mRNA
SEQUENCE    ACC=BG569293.1; NID=g13576946; CLONE=IMAGE:4722596; END=5'; LID=6989; SEQTYPE=EST; TRACE=44157214
...
SEQUENCE    ACC=AU099534.1; NID=g13550663; CLONE=HSI08034; END=5'; LID=8800; SEQTYPE=EST
//

此特定记录显示了一组笔录(显示在 SEQUENCE 系)起源于人类基因NAT 2,编码N-乙基转移酶。的 PROTSIM 线条显示与NAT2具有显着相似性的蛋白质,而 STS 线显示基因组中相应的序列标记位点。

要解析UniGene文件,请使用 Bio.UniGene 模块:

>>> from Bio import UniGene
>>> input = open("myunigenefile.data")
>>> record = UniGene.read(input)

record 返回 UniGene.read 是一个Python对象,其属性与UniGene记录中的字段相对应。例如,

>>> record.ID
"Hs.2"
>>> record.title
"N-acetyltransferase 2 (arylamine N-acetyltransferase)"

EXPRESSRESTR_EXPR 行存储为Python字符串列表:

[
    "bone",
    "connective tissue",
    "intestine",
    "liver",
    "liver tumor",
    "normal",
    "soft tissue/muscle tissue tumor",
    "adult",
]

STS , PROTSIM ,而且 SEQUENCE 行,将每一行中显示的键存储为属性:

>>> record.sts[0].acc
'PMC310725P3'
>>> record.sts[0].unists
'272646'

同样, PROTSIMSEQUENCE 线

要分析包含多个UniGene记录的文件,请使用 parse 功能 Bio.UniGene :

>>> from Bio import UniGene
>>> input = open("unigenerecords.data")
>>> records = UniGene.parse(input)
>>> for record in records:
...     print(record.ID)
...

使用代理

通常情况下,您不必担心使用代理,但如果这是您网络上的问题,请了解如何处理它。在内部, Bio.Entrez 使用标准Python库 urllib 用于访问NCBI服务器。这将检查名为 http_proxy 自动配置任何简单的代理。不幸的是,此模块不支持使用需要身份验证的代理。

您可以选择设置 http_proxy 环境变量一次(如何执行此操作将取决于您的操作系统)。或者,您可以在脚本开始时在Python中设置此功能,例如:

import os

os.environ["http_proxy"] = "http://proxyhost.example.com:8080"

看到 urllib documentation 了解更多详细信息。

示例

PubMed和Medline

如果您从事医学领域或对人类问题感兴趣(即使您不感兴趣,也很多时候!),PubMed(https://www.ncbi.nlm.nih.gov/PubMed/)是各种商品的绝佳来源。因此,与其他事情一样,我们希望能够从中获取信息并在Python脚本中使用它。

在本例中,我们将在PubMed中查询所有与兰花有关的文章(请参阅部分  使用示例 为了我们的动机)。我们首先检查一下这样的文章有多少:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.egquery(term="orchid")
>>> record = Entrez.read(stream)
>>> for row in record["eGQueryResult"]:
...     if row["DbName"] == "pubmed":
...         print(row["Count"])
...
463

现在我们使用 Bio.Entrez.efetch 功能可下载这463篇文章的PubMed ID:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esearch(db="pubmed", term="orchid", retmax=463)
>>> record = Entrez.read(stream)
>>> stream.close()
>>> idlist = record["IdList"]

这将返回一个Python列表,其中包含与兰花相关的所有文章的PubMed ID:

>>> print(idlist)
['18680603', '18665331', '18661158', '18627489', '18627452', '18612381',
'18594007', '18591784', '18589523', '18579475', '18575811', '18575690',
...

既然我们已经得到了它们,我们显然希望获得相应的Medline记录并从中提取信息。在这里,我们将下载Medline平面文件格式的Medline记录,并使用 Bio.Medline 模块来解析它们:

>>> from Bio import Medline
>>> stream = Entrez.efetch(db="pubmed", id=idlist, rettype="medline", retmode="text")
>>> records = Medline.parse(stream)

注意-我们刚刚在这里进行了单独的搜索和获取,NCBI非常希望您在这种情况下利用他们的历史支持。见章节  使用历史记录和WebEnv .

请记住 records 是一个迭代器,因此您只能迭代记录一次。如果您想保存记录,可以将它们转换为列表:

>>> records = list(records)

现在让我们重新检查这些记录,以打印有关每个记录的一些信息:

>>> for record in records:
...     print("title:", record.get("TI", "?"))
...     print("authors:", record.get("AU", "?"))
...     print("source:", record.get("SO", "?"))
...     print("")
...

其输出如下:

title: Sex pheromone mimicry in the early spider orchid (ophrys sphegodes):
patterns of hydrocarbons as the key mechanism for pollination by sexual
deception [In Process Citation]
authors: ['Schiestl FP', 'Ayasse M', 'Paulus HF', 'Lofstedt C', 'Hansson BS',
'Ibarra F', 'Francke W']
source: J Comp Physiol [A] 2000 Jun;186(6):567-74

特别有趣的是要注意的是作者列表,它作为标准Python列表返回。这使得使用标准Python工具可以轻松操作和搜索。例如,我们可以通过如下代码循环搜索一大堆条目来搜索特定的作者:

>>> search_author = "Waits T"
>>> for record in records:
...     if not "AU" in record:
...         continue
...     if search_author in record["AU"]:
...         print("Author %s found: %s" % (search_author, record["SO"]))
...

希望本节能让您了解Deliverz和Medline界面的强大功能和灵活性,以及如何一起使用它们。

搜索、下载和解析Deliverz核苷记录

这里我们将展示执行远程Deliverz查询的简单示例。节中  使用示例 在解析的例子中,我们谈到了使用NCBI的Spanz网站来搜索NCBI核苷酸数据库,以获得关于Cyperpedioideae的信息,我们的朋友,女士拖鞋兰花。现在,我们将看看如何使用Python脚本自动化该过程。在本例中,我们将展示如何连接、获取结果并解析它们,所有工作都由Zeroz模块完成。

首先,我们使用EGQuery来找出在实际下载之前将获得的结果数量。EGQuery会告诉我们在每个数据库中找到了多少个搜索结果,但对于这个例子,我们只对核苷感兴趣:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.egquery(term="Cypripedioideae")
>>> record = Entrez.read(stream)
>>> for row in record["eGQueryResult"]:
...     if row["DbName"] == "nuccore":
...         print(row["Count"])
...
4457

因此,我们预计将发现4457条z核苷酸记录(比2008年的814条记录有所增加;未来可能会继续增加)。如果您发现一些高得离谱的点击率,您可能需要重新考虑是否真的想下载所有它们,这是我们的下一步。让我们使用 retmax 将检索到的最大记录数限制为2008年可用数的参数:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esearch(
...     db="nucleotide", term="Cypripedioideae", retmax=814, idtype="acc"
... )
>>> record = Entrez.read(stream)
>>> stream.close()

在这里, record 是一个Python字典,包含搜索结果和一些辅助信息。仅供参考,让我们看看这个字典中存储的内容:

>>> print(record.keys())
['Count', 'RetMax', 'IdList', 'TranslationSet', 'RetStart', 'QueryTranslation']

首先,让我们看看有多少结果被发现:

>>> print(record["Count"])
'4457'

您可能预计这是814,这是我们要求检索的最大记录数。然而, Count 代表可用于该搜索的记录总数,而不是检索到的记录数量。检索到的记录存储在 record['IdList'] ,其中应该包含我们请求的总数:

>>> len(record["IdList"])
814

让我们看看前五个结果:

>>> record["IdList"][:5]
['KX265015.1', 'KX265014.1', 'KX265013.1', 'KX265012.1', 'KX265011.1']

我们可以使用下载这些记录 efetch .虽然您可以逐一下载这些记录,但为了减少NCBI服务器的负载,最好同时获取一堆记录,如下所示。然而,在这种情况下,您最好使用稍后在部分中描述的历史记录功能  使用历史记录和WebEnv .

>>> idlist = ",".join(record["IdList"][:5])
>>> print(idlist)
KX265015.1, KX265014.1, KX265013.1, KX265012.1, KX265011.1]
>>> stream = Entrez.efetch(db="nucleotide", id=idlist, retmode="xml")
>>> records = Entrez.read(stream)
>>> len(records)
5

这些记录中的每一条都对应于一条基因库记录。

>>> print(records[0].keys())
['GBSeq_moltype', 'GBSeq_source', 'GBSeq_sequence',
 'GBSeq_primary-accession', 'GBSeq_definition', 'GBSeq_accession-version',
 'GBSeq_topology', 'GBSeq_length', 'GBSeq_feature-table',
 'GBSeq_create-date', 'GBSeq_other-seqids', 'GBSeq_division',
 'GBSeq_taxonomy', 'GBSeq_references', 'GBSeq_update-date',
 'GBSeq_organism', 'GBSeq_locus', 'GBSeq_strandedness']

>>> print(records[0]["GBSeq_primary-accession"])
DQ110336

>>> print(records[0]["GBSeq_other-seqids"])
['gb|DQ110336.1|', 'gi|187237168']

>>> print(records[0]["GBSeq_definition"])
Cypripedium calceolus voucher Davis 03-03 A maturase (matR) gene, partial cds;
mitochondrial

>>> print(records[0]["GBSeq_organism"])
Cypripedium calceolus

您可以使用它来快速设置搜索-但对于大量使用,请参阅第节  使用历史记录和WebEnv .

搜索、下载和解析基因库记录

基因库记录格式是一种非常流行的保存有关序列、序列特征和其他相关序列信息的信息的方法。该格式是从https://www.ncbi.nlm.nih.gov/的NCBI数据库获取信息的好方法。

在这个示例中,我们将展示如何查询NCBI数据库,从查询中检索记录,然后使用 Bio.SeqIO - 部分涉及的一些内容  从网上解析基因库记录 .为了简单起见,这个例子 does not 利用WebEnv历史记录功能-请参阅部分  使用历史记录和WebEnv 为此

首先,我们要进行查询并找出要检索的记录的id。在这里我们将快速搜索我们最喜欢的生物之一, Opuntia (花椒仙人掌)。我们可以进行快速搜索并取回所有相应记录的GI(基因库标识符)。首先我们检查有多少条记录:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.egquery(term="Opuntia AND rpl16")
>>> record = Entrez.read(stream)
>>> for row in record["eGQueryResult"]:
...     if row["DbName"] == "nuccore":
...         print(row["Count"])
...
9

现在我们下载基因库标识符列表:

>>> stream = Entrez.esearch(db="nuccore", term="Opuntia AND rpl16")
>>> record = Entrez.read(stream)
>>> gi_list = record["IdList"]
>>> gi_list
['57240072', '57240071', '6273287', '6273291', '6273290', '6273289', '6273286',
'6273285', '6273284']

现在我们使用这些GI来下载SEN记录-请注意,对于较旧版本的Biopython,您必须向Deliverz提供逗号分隔的GI编号列表,从Biopython 1.59起,您可以传递一个列表,并为您转换:

>>> gi_str = ",".join(gi_list)
>>> stream = Entrez.efetch(db="nuccore", id=gi_str, rettype="gb", retmode="text")

如果您想查看原始的SEN文件,您可以从此流中读取并打印结果:

>>> text = stream.read()
>>> print(text)
LOCUS       AY851612                 892 bp    DNA     linear   PLN 10-APR-2007
DEFINITION  Opuntia subulata rpl16 gene, intron; chloroplast.
ACCESSION   AY851612
VERSION     AY851612.1  GI:57240072
KEYWORDS    .
SOURCE      chloroplast Austrocylindropuntia subulata
  ORGANISM  Austrocylindropuntia subulata
            Eukaryota; Viridiplantae; Streptophyta; Embryophyta; Tracheophyta;
            Spermatophyta; Magnoliophyta; eudicotyledons; core eudicotyledons;
            Caryophyllales; Cactaceae; Opuntioideae; Austrocylindropuntia.
REFERENCE   1  (bases 1 to 892)
  AUTHORS   Butterworth,C.A. and Wallace,R.S.
...

在这种情况下,我们只是获取原始记录。为了以更适合Python的形式获得记录,我们可以使用 Bio.SeqIO 将基因库数据解析为 SeqRecord 物体包括 SeqFeature 对象(参见第章  序列输入/输出 ):

>>> from Bio import SeqIO
>>> stream = Entrez.efetch(db="nuccore", id=gi_str, rettype="gb", retmode="text")
>>> records = SeqIO.parse(stream, "gb")

我们现在可以浏览记录并查看我们感兴趣的信息:

>>> for record in records:
...     print(f"{record.name}, length {len(record)}, with {len(record.features)} features")
...
AY851612, length 892, with 3 features
AY851611, length 881, with 3 features
AF191661, length 895, with 3 features
AF191665, length 902, with 3 features
AF191664, length 899, with 3 features
AF191663, length 899, with 3 features
AF191660, length 893, with 3 features
AF191659, length 894, with 3 features
AF191658, length 896, with 3 features

使用这些自动查询检索功能比手工操作是一个很大的优势。尽管该模块应该遵守NCBI每秒最多查询三个规则,但NCBI还有其他建议,例如避免高峰时段。见章节  埃斯珀兹准则 .特别要注意的是,为了简单起见,这个例子没有使用WebEnv历史记录功能。您应该将其用于任何重要的搜索和下载工作,请参见  使用历史记录和WebEnv .

最后,如果计划重复您的分析,而不是从NCBI下载文件并立即解析它们(如本示例中所示),您应该只下载记录 once 并将它们保存到您的硬盘,然后解析本地文件。

寻找一个有机体的谱系

以植物为例,现在让我们找到西兰科兰花的谱系。首先,我们在分类数据库中搜索塞浦路斯科,这恰好会产生一个NCBI分类标识符:

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esearch(db="Taxonomy", term="Cypripedioideae")
>>> record = Entrez.read(stream)
>>> record["IdList"]
['158330']
>>> record["IdList"][0]
'158330'

现在,我们使用 efetch 要在分类数据库中下载此条目,然后解析它:

>>> stream = Entrez.efetch(db="Taxonomy", id="158330", retmode="xml")
>>> records = Entrez.read(stream)

同样,此记录存储了大量信息:

>>> records[0].keys()
['Lineage', 'Division', 'ParentTaxId', 'PubDate', 'LineageEx',
 'CreateDate', 'TaxId', 'Rank', 'GeneticCode', 'ScientificName',
 'MitoGeneticCode', 'UpdateDate']

我们可以直接从这个记录中得到血统:

>>> records[0]["Lineage"]
'cellular organisms; Eukaryota; Viridiplantae; Streptophyta; Streptophytina;
 Embryophyta; Tracheophyta; Euphyllophyta; Spermatophyta; Magnoliopsida;
 Liliopsida; Asparagales; Orchidaceae'

记录数据包含的不仅仅是此处显示的信息-例如,查看 "LineageEx" 而不是 "Lineage" 并且您还将获得谱系条目的NCBI分类单元标识符。

使用历史记录和WebEnv

通常您会想要进行一系列链接查询。最通常的情况是,运行搜索,也许是细化搜索,然后检索详细的搜索结果。你 can 可以通过向Deliverz拨打一系列单独的电话来做到这一点。然而,NCBI希望您利用他们的历史支持-例如将ESSEARCH和EFetch结合起来。

历史支持的另一个典型用途是将EPost和EFetch结合起来。您使用EPost上传标识符列表,从而启动新的历史记录会话。然后通过引用会话(而不是标识符)使用EFetch下载记录。

使用历史记录搜索和下载序列

假设我们要搜索和下载所有 Opuntia rpl16核苷酸序列,并将它们存储在FASTA文件中。节所列  搜索、下载和解析基因库记录 ,我们可以天真地结合 Bio.Entrez.esearch() 获取加入号列表,然后致电 Bio.Entrez.efetch() 下载它们全部。

然而,批准的方法是使用历史记录功能运行搜索。然后,我们可以通过参考搜索结果来获取结果-NCBI可以预测和缓存这些结果。

为此,请致电 Bio.Entrez.esearch() 正常,但还有额外的论点 usehistory="y" ,

>>> from Bio import Entrez
>>> Entrez.email = "history.user@example.com"  # Always tell NCBI who you are
>>> stream = Entrez.esearch(
...     db="nucleotide", term="Opuntia[orgn] and rpl16", usehistory="y", idtype="acc"
... )
>>> search_results = Entrez.read(stream)
>>> stream.close()

如前所述(请参阅部分  搜索、下载和解析Deliverz核苷记录 ),该文档输出包括第一个 retmax 搜索结果,带有 retmax 默认为20:

>>> acc_list = search_results["IdList"]
>>> count = int(search_results["Count"])
>>> len(acc_list)
20
>>> count
28

您还将获得两条额外的信息, WebEnv 会话cookie,以及 QueryKey :

>>> webenv = search_results["WebEnv"]
>>> query_key = search_results["QueryKey"]

将这些值存储在变量中 session_cookiequery_key 我们可以使用它们作为参数 Bio.Entrez.efetch() 而不是将GI号作为标识符。

虽然对于小型搜索,您可能可以一次下载所有内容,但最好批量下载。您使用 retstartretmax 参数用于指定您想要返回的搜索结果范围(使用从零开始计数的条目以及要返回的最大结果数)。请注意,如果Biopython在与NCBI通信时遇到暂时故障(例如HTT500响应),它将自动再试几次。例如,

# This assumes you have already run a search as shown above,
# and set the variables count, webenv, query_key

batch_size = 3
output = open("orchid_rpl16.fasta", "w")
for start in range(0, count, batch_size):
    end = min(count, start + batch_size)
    print("Going to download record %i to %i" % (start + 1, end))
    stream = Entrez.efetch(
        db="nucleotide",
        rettype="fasta",
        retmode="text",
        retstart=start,
        retmax=batch_size,
        webenv=webenv,
        query_key=query_key,
        idtype="acc",
    )
    data = stream.read()
    stream.close()
    output.write(data)
output.close()

为了说明起见,此示例以三个批次下载了FASTA记录。除非您正在下载基因组或染色体,否则您通常会选择更大的批量。

使用历史搜索和下载摘要

这是另一个历史例子,搜索去年发表的有关 Opuntia ,然后将它们下载到MedLine格式的文件中:

from Bio import Entrez

Entrez.email = "history.user@example.com"
search_results = Entrez.read(
    Entrez.esearch(
        db="pubmed", term="Opuntia[ORGN]", reldate=365, datetype="pdat", usehistory="y"
    )
)
count = int(search_results["Count"])
print("Found %i results" % count)

batch_size = 10
output = open("recent_orchid_papers.txt", "w")
for start in range(0, count, batch_size):
    end = min(count, start + batch_size)
    print("Going to download record %i to %i" % (start + 1, end))
    stream = Entrez.efetch(
        db="pubmed",
        rettype="medline",
        retmode="text",
        retstart=start,
        retmax=batch_size,
        webenv=search_results["WebEnv"],
        query_key=search_results["QueryKey"],
    )
    data = stream.read()
    stream.close()
    output.write(data)
output.close()

在撰写本文时,这给出了28个匹配项-但由于这是日期相关搜索,因此这当然会有所不同。节所述  解析Medline记录 上面,您可以使用 Bio.Medline 解析保存的记录。

搜索引文

回到部分  ELink:在NCBI Deliverz中搜索相关项目 我们提到ELink可以用于搜索给定论文的引用。不幸的是,这只涵盖PubMed Central索引的期刊(为PubMed中的所有期刊这样做意味着NIH需要做更多的工作)。让我们尝试一下Biopython DBC解析器论文(PubMed ID 14630660):

>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com"  # Always tell NCBI who you are
>>> pmid = "14630660"
>>> results = Entrez.read(
...     Entrez.elink(dbfrom="pubmed", db="pmc", LinkName="pubmed_pmc_refs", id=pmid)
... )
>>> pmc_ids = [link["Id"] for link in results[0]["LinkSetDb"][0]["Link"]]
>>> pmc_ids
['2744707', '2705363', '2682512', ..., '1190160']

伟大的-十一篇文章。但为什么没有找到Biopython应用笔记(PubMed ID 19304878)?好吧,正如您可能从变量名称中猜到的那样,实际上不是PubMed ID,而是PubMed Central ID。我们的应用笔记是该列表中的第三篇引用论文PMCID 2682512。

那么,如果(像我一样)您宁愿取回PubMed ID列表怎么办?好吧,我们可以再次致电ELink来翻译它们。这将成为一个两步过程,因此现在您应该期望使用历史功能来完成它(第节  使用历史记录和WebEnv ).

但首先,采取更简单的方法,对ELink进行第二次(单独)调用:

>>> results2 = Entrez.read(
...     Entrez.elink(dbfrom="pmc", db="pubmed", LinkName="pmc_pubmed", id=",".join(pmc_ids))
... )
>>> pubmed_ids = [link["Id"] for link in results2[0]["LinkSetDb"][0]["Link"]]
>>> pubmed_ids
['19698094', '19450287', '19304878', ..., '15985178']

这次,您可以立即发现Biopython应用笔记是第三次点击(PubMed ID 19304878)。

现在,让我们再做一遍,但根据历史. TODO .

最后,不要忘记包括您的 own Deliverz通话中的电子邮件地址。