Python etree.ElementTree提取含HTML标签的XML文本时出现截断问题
核心原因
XML元素内嵌<i>这类子标签时,文本会被拆分存储:父元素的text存储第一个子标签前的内容,内嵌子标签的text存储标签包裹的内容,子标签的tail存储标签结束后到父元素闭合前的内容,直接读取父元素的.text只能拿到第一部分文本。
方案1:使用标准库xml.etree.ElementTree实现
写一个递归拼接函数处理所有文本节点:
import xml.etree.ElementTree as ET def get_full_text(element): full_text = [] if element.text: full_text.append(element.text) for child in element: full_text.append(get_full_text(child)) if child.tail: full_text.append(child.tail) return ''.join(full_text) # 业务逻辑改造 xmldata = 'directory/to/data.xml' tree = ET.parse(xmldata) root = tree.getroot() abstracts = {} titles = {} # 遍历每一篇独立文章节点,根据实际XML结构调整标签名 for idx, article in enumerate(root.findall('PubmedArticle')): # 提取完整标题 title_elem = article.find('.//ArticleTitle') if title_elem is not None: titles[idx] = get_full_text(title_elem) # 提取完整摘要 abstract_elem = article.find('.//AbstractText') if abstract_elem is not None: abstracts[idx] = get_full_text(abstract_elem)
方案2:使用lxml实现(更简洁)
之前用lxml出错是因为用了全局路径//AbstractText匹配了文档所有摘要节点,改成相对路径匹配单篇文章下的节点,再用string()方法自动拼接所有内嵌文本即可:
from lxml import etree xmldata = 'directory/to/data.xml' tree = etree.parse(xmldata) abstracts = {} titles = {} # 先匹配所有独立文章节点 for idx, article in enumerate(tree.xpath('//PubmedArticle')): # 匹配当前文章下的标题,自动拼接所有文本 title = article.xpath('.//ArticleTitle')[0].xpath('string(.)') titles[idx] = title # 匹配当前文章下的摘要 abstract = article.xpath('.//AbstractText')[0].xpath('string(.)') abstracts[idx] = abstract
两种方案都可以保留原始文本的完整内容,不会丢失内嵌标签包裹的文本。
内容的提问来源于stack exchange,提问作者deardirestraits
相关产品推荐
相关产品推荐

