Python处理带命名空间XML需显式声明命名空间映射字典,XPath中用“前缀:标签”形式查找,如ns:channel;默认命名空间也须指定前缀,URI必须完全匹配,不支持*通配符跨空间匹配。
Python处理带命名空间的XML,关键在于正确声明和使用命名空间前缀,否则find、findall等方法会找不到元素。
理解命名空间在ElementTree中的表示方式
ElementTree默认不自动识别XML文档中的xmlns声明。即使XML里写了xmlns="http://example.com/ns",你也不能直接用root.find("item")——必须显式传入命名空间映射字典。
- 命名空间映射是一个字典,键是前缀(可自定义),值是URI字符串
- XPath表达式中需用
prefix:tagname写法,如"ns:item" - 默认命名空间(无前缀的
xmlns="...")也要给它起个前缀,不能留空
使用namespaces参数进行查找
这是最常用也最推荐的方式:构造命名空间字典,传给find、findall、iterfind等方法。
例如有如下XML:
立即学习“Python免费学习笔记(深入)”;
My Feed Post 1
对应代码为:
import xml.etree.ElementTree as ETtree = ET.parse("feed.xml") root = tree.getroot()
声明命名空间:这里用"ns"作为前缀
ns = {"ns": "https://www./link/ff4776b449efb88b35fbf6187af9771e"}
正确查找
channel = root.find("ns:channel", namespaces=ns) title = channel.find("ns:title", namespaces=ns) items = channel.findall("ns:item", namespaces=ns)
处理多个命名空间或带前缀的XML
如果XML中用了多个带前缀的命名空间(如xmlns:dc="http://purl.org/dc/elements/1.1/"),只需在字典中一并声明:
ns = {
"rss": "https://www./link/ff4776b449efb88b35fbf6187af9771e",
"dc": "http://purl.org/dc/elements/1.1/"
}
查找 dc:creator
creator = item.find("dc:creator", namespaces=ns)
注意:前缀名(如"dc")可以任意取,只要和XPath中一致即可;URI必须完全匹配XML中声明的值(包括末尾斜杠)。
避免常见坑:默认命名空间与通配符
ElementTree不支持*通配符跨命名空间匹配。不要写root.findall("*:item")——它不会生效。
- 若不确定命名空间,可先用
root.tag打印根元素全名,如{https://www./link/ff4776b449efb88b35fbf6187af9771e}rss,从中提取URI - 想忽略命名空间?可用正则提取本地名:
elem.tag.split("}")[-1],再遍历比对,但性能较差,仅作备用 - 第三方库如
lxml支持etree.XPath和更灵活的命名空间处理,适合复杂场景









