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

如何用Python提取PubMed XML文章字段并构建SQL数据库?

解决方案:用BioPython Entrez提取PubMed结构化摘要字段

关键背景:PubMed XML中Methods/Results的存储位置

PubMed的结构化摘要内容会放在<AbstractText>标签下,通过Label属性区分不同部分(比如Label="METHODS"、Label="RESULTS");非结构化摘要则没有单独拆分,只能从完整摘要里提取(或无法拆分)。另外,部分文献可能在<Article>节点下有<Methods>标签,但该字段并非所有文献都具备,优先级低于结构化摘要的对应部分。

完整Python实现步骤

1. 安装依赖

pip install biopython sqlalchemy
  • biopython:用于调用NCBI Entrez API并解析PubMed XML
  • sqlalchemy:用于快速构建SQL数据库(支持SQLite、MySQL等)

2. 核心代码实现

from Bio import Entrez
from sqlalchemy import create_engine, Column, String, Text, Integer
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import xml.etree.ElementTree as ET

# 配置NCBI邮箱(必填,NCBI要求识别请求来源)
Entrez.email = "your_email@example.com"

# 定义SQL数据表模型
Base = declarative_base()
class PubMedArticle(Base):
    __tablename__ = 'pubmed_articles'
    pmid = Column(String(20), primary_key=True)
    title = Column(Text)
    year = Column(Integer)
    doi = Column(String(100))
    journal_name = Column(Text)
    first_author = Column(String(100))
    abstract = Column(Text)
    methods = Column(Text)
    results = Column(Text)
    # 备注:PubMed公开API不提供全文内容,仅能获取摘要
    content = Column(Text, default="PubMed仅提供摘要,无公开全文内容")

# 初始化数据库(以SQLite为例,可替换为MySQL等)
engine = create_engine('sqlite:///pubmed_db.sqlite')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

def fetch_and_parse_pubmed(pmid_list):
    # 批量获取PubMed XML数据
    handle = Entrez.efetch(db="pubmed", id=','.join(pmid_list), retmode="xml")
    xml_data = handle.read()
    handle.close()
    
    root = ET.fromstring(xml_data)
    
    for article in root.findall('.//PubmedArticle'):
        # 提取PMID
        pmid = article.find('.//PMID').text
        
        # 提取标题
        title = article.find('.//ArticleTitle').text
        
        # 提取发表年份
        pub_date = article.find('.//PubDate')
        year = pub_date.find('Year')
        year = year.text if year is not None else None
        
        # 提取DOI
        doi = None
        for id_info in article.findall('.//ArticleId'):
            if id_info.get('IdType') == 'doi':
                doi = id_info.text
                break
        
        # 提取期刊名
        journal_name = article.find('.//Journal/Title').text
        
        # 提取第一作者
        first_author = None
        author_list = article.findall('.//Author')
        if author_list:
            last_name = author_list[0].find('LastName').text
            fore_name = author_list[0].find('ForeName').text
            first_author = f"{last_name}, {fore_name}"
        
        # 提取完整摘要及结构化Methods/Results
        abstract = ""
        methods = ""
        results = ""
        abstract_texts = article.findall('.//AbstractText')
        for abs_text in abstract_texts:
            abs_content = abs_text.text or ""
            abstract += abs_content + "\n"
            # 按Label属性识别结构化部分
            label = abs_text.get('Label')
            if label and label.upper() == "METHODS":
                methods = abs_content
            elif label and label.upper() == "RESULTS":
                results = abs_content
        
        # 若结构化摘要无Methods,尝试提取Article节点下的Methods字段
        if not methods:
            article_methods = article.find('.//Methods')
            methods = article_methods.text if article_methods is not None else ""
        
        # 写入数据库
        db_article = PubMedArticle(
            pmid=pmid,
            title=title,
            year=int(year) if year else None,
            doi=doi,
            journal_name=journal_name,
            first_author=first_author,
            abstract=abstract.strip(),
            methods=methods.strip(),
            results=results.strip()
        )
        session.add(db_article)
    
    session.commit()
    print(f"成功处理{len(pmid_list)}篇文献,数据已存入数据库")

# 示例调用:替换为目标PMID列表
if __name__ == "__main__":
    sample_pmids = ["31234567", "32109876"]
    fetch_and_parse_pubmed(sample_pmids)

关键注意事项

  1. Content字段说明:PubMed公开API仅提供摘要信息,不开放全文获取权限。若需全文,需通过付费数据库或PubMed Central(仅限开放获取文献)获取,超出公开API范围。
  2. 结构化摘要兼容性:并非所有文献都有拆分好的Methods/Results部分,非结构化摘要对应的字段会为空,此时可结合NLP工具从完整摘要中提取(需额外开发)。
  3. NCBI请求限制:NCBI对API请求频率有限制(每秒最多3次),批量处理大量文献时需添加延时(如time.sleep(1)),避免被封禁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 05:58:32