如何通过Biopython的Entrez.esearch获取超过9999条PubMed文献?
解决PubMed API通过Biopython获取超过9999条文献的问题
问题场景
使用Biopython的Entrez模块查询PubMed文献时,无论将retmax参数设置多大,最多只能返回9999条结果,但手动查询PubMed时,符合条件的文献数量远超过这个数。原代码示例:
from Bio import Entrez from io import StringIO import csv # Set email and API key (replace 'youremail' and 'yourapikey' with your own) Entrez.email = 'banana@gmail' #just dummy Entrez.api_key = 'banana' #just dummy # Define search terms and time window search_term = 'cancer' start_date = '2015/01/01' end_date = '2016/08/30' # Define search query query = f'{search_term}[Title/Abstract] AND ("{start_date}"[Date - Publication] : "{end_date}"[Date - Publication])' # Search PUBMED using the query handle = Entrez.esearch(db='pubmed', term=query, retmax=10000) record = Entrez.read(handle) id_list = record['IdList'] len(id_list)
解决方案
1. 获取准确的文献总数
Entrez.esearch返回的record字典中,'Count'字段存储了符合查询条件的准确总文献数,不受retmax限制。可以通过int(record['Count'])直接获取这个数值。
2. 分批拉取所有文献ID
PubMed API对单次esearch请求的retmax上限是10000,因此需要通过循环配合retstart参数(指定从第几条结果开始返回)分批拉取所有ID:
- 每次请求拉取10000条,剩余不足10000条时取剩余数量
- 逐步更新
retstart的数值,直到覆盖所有总条数
3. 遵守API调用限制
使用API Key后,PubMed API允许每秒最多10次请求;无API Key则为3次。建议在循环中加入短暂延时(如0.1秒),避免触发限流机制。
修改后的完整代码
from Bio import Entrez import time # 配置Entrez(替换为自己的邮箱和API Key) Entrez.email = 'your_real_email@example.com' Entrez.api_key = 'your_real_api_key' # 定义查询参数 search_term = 'cancer' start_date = '2015/01/01' end_date = '2016/08/30' query = f'{search_term}[Title/Abstract] AND ("{start_date}"[Date - Publication] : "{end_date}"[Date - Publication])' # 第一步:获取总文献数和初始ID列表 handle = Entrez.esearch(db='pubmed', term=query, retmax=10000) record = Entrez.read(handle) total_count = int(record['Count']) id_list = record['IdList'] # 第二步:分批拉取剩余的ID remaining = total_count - len(id_list) while remaining > 0: retstart = len(id_list) # 每次最多拉取10000条,剩余不足则取剩余数 retmax = min(10000, remaining) handle = Entrez.esearch(db='pubmed', term=query, retstart=retstart, retmax=retmax) batch_record = Entrez.read(handle) id_list.extend(batch_record['IdList']) remaining = total_count - len(id_list) # 加延时避免限流 time.sleep(0.1) # 输出结果 print(f"准确总文献数:{total_count}") print(f"成功获取的ID数量:{len(id_list)}") # 后续可根据id_list获取详细文献信息(如使用Entrez.efetch)
补充说明
如果需要获取文献的详细内容(标题、摘要等),可以用Entrez.efetch配合获取到的id_list,同样建议分批请求(每次最多获取200条,避免请求过大),并遵守API调用限制。
内容的提问来源于stack exchange,提问作者dbfk2000
相关产品推荐
相关产品推荐

