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

使用Python的cElementTree提取DrugBank XML数据的方法问询

嘿,我之前刚好处理过DrugBank的XML数据集,用Python的cElementTree(在Python3里其实已经整合到xml.etree.ElementTree中了,性能一样出色)提取数据核心要注意命名空间这个容易踩的坑——你的XML里带了xmlns="http://www.drugbank.ca",直接用标签名查找会找不到元素的。下面给你一步步拆解实现:

第一步:导入模块并解析XML

首先导入对应的模块,然后加载你的XML文件:

# Python2用这个,Python3也兼容,或者直接import xml.etree.ElementTree as ET
import xml.etree.cElementTree as ET

# 解析XML文件
tree = ET.parse('你的drugbank文件名.xml')
root = tree.getroot()
第二步:处理命名空间

因为所有元素都属于http://www.drugbank.ca这个命名空间,我们需要定义一个命名空间映射,这样查找元素时更清晰:

# 定义命名空间别名,方便后续查找
ns = {'db': 'http://www.drugbank.ca'}
第三步:提取基础数据示例

比如遍历所有药物,提取它们的主ID、类型、创建和更新时间:

for drug in root.findall('db:drug', ns):
    # 获取drug标签的属性
    drug_type = drug.get('type')
    created = drug.get('created')
    updated = drug.get('updated')
    
    # 找到primary为true的drugbank-id
    primary_id = None
    for db_id in drug.findall('db:drugbank-id', ns):
        if db_id.get('primary') == 'true':
            primary_id = db_id.text
            break  # 找到主ID就停止遍历
    
    print(f"主ID: {primary_id}, 类型: {drug_type}, 创建时间: {created}, 更新时间: {updated}")
第四步:提取特定药物的信息

如果要定位到某个具体药物(比如DB00001),可以这样做:

target_id = 'DB00001'
target_drug = None

for drug in root.findall('db:drug', ns):
    for db_id in drug.findall('db:drugbank-id', ns):
        if db_id.get('primary') == 'true' and db_id.text == target_id:
            target_drug = drug
            break
    if target_drug:
        break

if target_drug:
    # 假设你要提取药物名称(XML里应该有<name>标签)
    drug_name = target_drug.find('db:name', ns).text
    print(f"找到目标药物: {drug_name} (ID: {target_id})")
    # 你可以继续提取其他标签,比如适应症、分子式等,方法都是用find/findall加命名空间
处理大XML文件的优化

如果你的DrugBank XML文件特别大(毕竟数据集不小),直接用parse会占用大量内存,建议用迭代解析的方式,边解析边处理,处理完就释放内存:

for event, elem in ET.iterparse('你的drugbank文件名.xml', events=('end',)):
    # 只处理</drug>标签结束的事件
    if elem.tag == '{http://www.drugbank.ca}drug':
        # 提取主ID
        primary_id = None
        for db_id in elem.findall('{http://www.drugbank.ca}drugbank-id'):
            if db_id.get('primary') == 'true':
                primary_id = db_id.text
                break
        print(f"处理药物: {primary_id}")
        
        # 清理当前元素,释放内存
        elem.clear()
        # 清理父节点的引用(可选,进一步节省内存)
        while elem.getprevious() is not None:
            del elem.getparent()[0]

最后提醒一下:所有元素查找都必须带上命名空间,不管是用find、findall还是迭代解析时的标签判断,否则会找不到任何元素哦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:45:44