You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Biopython从PubMed检索COVID-19文献时,如何自动下载XML或文本格式文件?

解决方案:从PubMed下载COVID-19文献的XML/文本文件

你已经用Biopython的Entrez模块搞定了文献标题的获取,要扩展到下载XML或文本格式的文件其实没那么复杂,只需要调整Entrez.efetch的参数,再把返回的内容写入本地文件就行。下面分两种格式给你具体实现:

一、下载XML格式的文献文件

PubMed的XML数据可以直接通过efetch获取,我们只需要把返回的字节流写入.xml文件即可。修改你的脚本如下:

from Bio import Entrez
import os

def search(query):
    Entrez.email = 'your.email@example.com'
    handle = Entrez.esearch(db='pubmed', sort='relevance', retmax='20', retmode='xml', term=query)
    results = Entrez.read(handle)
    return results

def fetch_and_save_xml(id_list, save_dir='pubmed_xmls'):
    # 创建保存目录,避免报错
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    Entrez.email = 'your.email@example.com'
    
    # 方式1:把所有文献保存到同一个XML文件里
    ids = ','.join(id_list)
    handle = Entrez.efetch(db='pubmed', retmode='xml', id=ids)
    with open(os.path.join(save_dir, 'all_covid_papers.xml'), 'wb') as f:
        f.write(handle.read())
    print(f"所有文献XML已保存到 {os.path.join(save_dir, 'all_covid_papers.xml')}")
    
    # 方式2:按文献ID逐个单独保存(可选,方便后续单篇处理)
    for paper_id in id_list:
        single_handle = Entrez.efetch(db='pubmed', retmode='xml', id=paper_id)
        with open(os.path.join(save_dir, f'{paper_id}.xml'), 'wb') as f:
            f.write(single_handle.read())
        print(f"文献ID {paper_id} 的XML已保存")

if __name__ == '__main__':
    results = search('covid-19')
    id_list = results['IdList']
    fetch_and_save_xml(id_list)

二、下载纯文本格式的文献摘要/全文

如果需要纯文本格式,PubMed支持通过rettype参数指定获取内容类型:比如abstract(仅摘要)或者txt(全文,但只有开放获取的文献能拿到完整全文)。修改后的函数如下:

from Bio import Entrez
import os

def search(query):
    Entrez.email = 'your.email@example.com'
    handle = Entrez.esearch(db='pubmed', sort='relevance', retmax='20', retmode='xml', term=query)
    results = Entrez.read(handle)
    return results

def fetch_and_save_text(id_list, save_dir='pubmed_texts', rettype='abstract'):
    if not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    Entrez.email = 'your.email@example.com'
    for paper_id in id_list:
        # 设置retmode为'text',rettype指定要获取的文本类型
        handle = Entrez.efetch(db='pubmed', retmode='text', rettype=rettype, id=paper_id)
        text_content = handle.read()
        # 写入文件时指定编码,避免乱码
        with open(os.path.join(save_dir, f'{paper_id}_{rettype}.txt'), 'w', encoding='utf-8') as f:
            f.write(text_content)
        print(f"文献ID {paper_id} 的{rettype}文本已保存")

if __name__ == '__main__':
    results = search('covid-19')
    id_list = results['IdList']
    # 先获取摘要试试
    fetch_and_save_text(id_list, rettype='abstract')
    # 如果想尝试获取全文,把rettype改成'txt'(注意:非开放获取文献拿不到全文)
    # fetch_and_save_text(id_list, rettype='txt')

几个关键注意点

  • 一定要设置Entrez.email:NCBI要求所有API请求都要提供邮箱,否则大概率会被限流甚至封禁访问。
  • 注意请求频率:NCBI对API请求频率有限制,短时间内大量请求可能会被暂时限制,要是需要批量获取几百上千篇文献,记得加个time.sleep(1)之类的延迟。
  • 全文获取限制:不是所有PubMed文献都能拿到全文,只有开放获取的文献才能通过rettype='txt'获取到完整内容,其他的只能拿到摘要部分。

内容的提问来源于stack exchange,提问作者user14762294

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 18:13:14