获取XML数据中的唯一值:用lxml提取<updated>日期及统计问题
解决lxml提取/日期及统计唯一值的问题
嘿,我来帮你搞定这个问题!你说用lxml提取日期时输出是空列表[],大概率是XML命名空间在搞鬼——很多类似Atom feed的XML文档都会带有默认命名空间,直接用简单的XPath路径根本找不到节点。下面分步骤给你解决:
第一步:正确提取字段的日期
情况1:XML带有默认命名空间(最常见)
比如你的XML结构大概是这样的:
<feed xmlns="http://www.w3.org/2005/Atom"> <entry> <updated>2018-02-27T10:15:30Z</updated> </entry> <entry> <updated>2018-02-27T14:20:00Z</updated> </entry> </feed>
这时候需要在lxml里指定命名空间映射,再用带命名空间前缀的XPath查询:
from lxml import etree # 加载XML(这里以字符串为例,也可以用parse()加载本地/远程文件) xml_content = """ <feed xmlns="http://www.w3.org/2005/Atom"> <entry> <updated>2018-02-27T10:15:30Z</updated> </entry> <entry> <updated>2018-02-27T14:20:00Z</updated> </entry> <entry> <updated>2018-02-28T09:00:00Z</updated> </entry> <entry> <updated>2018-03-01T16:45:00Z</updated> </entry> </feed> """ # 解析XML内容 tree = etree.fromstring(xml_content) # 定义命名空间映射(前缀可以随便取,比如atom) ns = {'atom': 'http://www.w3.org/2005/Atom'} # 提取所有<entry>下的<updated>文本内容 updated_elements = tree.xpath('//atom:entry/atom:updated/text()', namespaces=ns) # 提取纯日期部分(因为<updated>是ISO8601格式,分割T就能拿到日期) dates = [date.split('T')[0] for date in updated_elements] print(dates) # 输出: ['2018-02-27', '2018-02-27', '2018-02-28', '2018-03-01']
情况2:XML没有命名空间
如果你的XML不带任何命名空间,那直接用简单的XPath就能提取:
updated_elements = tree.xpath('//entry/updated/text()') dates = [date.split('T')[0] for date in updated_elements]
第二步:统计唯一日期的数量
这一步超简单,用Python的**集合(set)**自动去重,然后取长度就行:
unique_dates = set(dates) unique_count = len(unique_dates) print(f"唯一日期数量:{unique_count}") # 输出: 唯一日期数量:3
为什么之前输出[]?
大概率是你忽略了命名空间的存在,导致XPath找不到对应的节点。你可以先打印XML根节点的命名空间,确认是否存在:
print(tree.nsmap) # 输出类似: {None: 'http://www.w3.org/2005/Atom'}
如果输出里有None对应的URL,就说明有默认命名空间,必须用命名空间映射来查询节点。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

