我正在尝试使用以下代码搜索一些文章:
handle = Entrez.esearch(db="pubmed", term="lung+cancer")
record = Entrez.read(handle)
从record['Count']
我可以看到有 293279 个结果,但是当我查看record['IdList']
它时,它只给了我 20 个 ID。这是为什么?如何获取所有 293279 条记录?
返回的默认记录数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
.
EPost 上传 UI 列表,用于后续搜索策略;有关更多信息,请参阅EPost 帮助页面。它可通过 Biopython
Bio.Entrez.epost()
函数获得。举个例子说明什么时候有用,假设你有一长串要使用 EFetch 下载的 ID(可能是序列,可能是引用——任何东西)。当您使用 EFetch 发出请求时,您的 ID 列表、数据库等都将变成发送到服务器的长 URL。如果您的 ID 列表很长,则此 URL 会变长,并且长 URL 可能会中断(例如,某些代理不能很好地处理)。
相反,您可以将其分为两个步骤,首先使用 EPost 上传 ID 列表(这在内部使用“HTML post”,而不是“HTML get”,以解决长 URL 问题)。借助历史记录支持,您可以参考这个长长的 ID 列表,并使用 EFetch 下载相关数据。
[...] 返回的 XML 包括两个重要的字符串,QueryKey 和 WebEnv,它们共同定义了您的历史会话。您将提取这些值以用于另一个 Entrez 调用,例如 EFetch。
阅读第 9.15 章:使用历史搜索和下载序列以了解如何使用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
success = False
while attempt < 3 and not success:
attempt += 1
try:
fetch_handle = Entrez.efetch(db="pubmed",
retstart=start, retmax=batch_size,
webenv=webenv, query_key=query_key)
success = True
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()