我正在尝试使用以下代码搜索一些文章:
handle = Entrez.esearch(db="pubmed", term="lung+cancer")
record = Entrez.read(handle)
从record['Count']
我可以看到有293279个结果,但是当我查看record['IdList']
时,它只给了我20个ID。这是为什么?我如何获得所有293279记录?
答案 0 :(得分:3)
Entrez.esearch
返回的默认记录数为20.这是为了防止NCBI的服务器过载。要获取完整的记录列表,请更改retmax
参数:
>>> from Bio import Entrez
>>> Entrez.email = "A.N.Other@example.com" # Always tell NCBI who you are
>>> handle = Entrez.esearch(db="pubmed", term="lung+cancer")
>>> record = Entrez.read(handle)
>>> count = record['Count']
>>> handle = Entrez.esearch(db="pubmed", term="lung+cancer", retmax=count)
>>> record = Entrez.read(handle)
>>> print len(record['IdList'])
293279
下载所有记录的方法是使用Entrez.epost
。
来自chapter 9.4 of the BioPython tutorial:
EPost上传用于后续搜索策略的UI列表;有关详细信息,请参阅EPost help page。它可以通过
Bio.Entrez.epost()
函数从Biopython获得。举一个有用的例子,假设你有一个很长的ID列表要用EFetch下载(可能是序列,也可能是引用 - 任何东西)。当您使用EFetch发出请求时,您的ID列表,数据库等都会变成发送到服务器的长URL。如果您的ID列表很长,则此网址会变长,并且长网址可能会中断(例如,某些代理无法很好地处理)。
相反,您可以将其分解为两个步骤,首先使用EPost上传ID列表(这在内部使用“HTML post”,而不是“HTML get”,绕过长URL问题)。通过历史记录支持,您可以参考这长长的ID列表,并使用EFetch下载相关数据。
[...] 返回的XML包括两个重要的字符串,QueryKey和WebEnv,它们共同定义了您的历史会话。您将提取这些值以用于其他Entrez调用,例如EFetch。
阅读chapter 9.15.: Searching for and downloading sequences using the history,了解如何使用QueryKey
和WebEnv
一个完整的工作示例将是:
from Bio import Entrez
import time
Entrez.email = "A.N.Other@example.com"
handle = Entrez.esearch(db="pubmed", term="lung+cancer")
record = Entrez.read(handle)
count = int(record['Count'])
handle = Entrez.esearch(db="pubmed", term="lung+cancer", retmax=count)
record = Entrez.read(handle)
id_list = record['IdList']
post_xml = Entrez.epost("pubmed", id=",".join(id_list))
search_results = Entrez.read(post_xml)
webenv = search_results["WebEnv"]
query_key = search_results["QueryKey"]
try:
from urllib.error import HTTPError # for Python 3
except ImportError:
from urllib2 import HTTPError # for Python 2
batch_size = 200
out_handle = open("lung_cancer.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))
attempt = 0
while attempt < 3:
attempt += 1
try:
fetch_handle = Entrez.efetch(db="pubmed",
retstart=start, retmax=batch_size,
webenv=webenv, query_key=query_key)
except HTTPError as err:
if 500 <= err.code <= 599:
print("Received error from server %s" % err)
print("Attempt %i of 3" % attempt)
time.sleep(15)
else:
raise
data = fetch_handle.read()
fetch_handle.close()
out_handle.write(data)
out_handle.close()