发布于2026-07-20 阅读(0)
扫一扫,手机访问
本地文件用ElementTree.parse(),网络XML字符串用fromstring();命名空间需显式声明或用".//tag"模糊匹配;text为空时应strip()判断,含子标签用itertext()拼接。

数据来源决定了一切。本地磁盘上的文件,直接调用 parse() 就行,它只认文件路径或类文件对象。但如果你是从网络请求拿到的 XML 字符串——比如 response.text——就得用 fromstring()。搞混了?那等着 ParseError: not well-formed (invalid token) 吧,因为 parse() 根本不接受纯字符串。
parse("data.xml"):直接读磁盘,返回 ElementTree 实例fromstring(response.text):处理网络响应体,返回根 Elementrequests.get().content(bytes 类型),先 decode 成 str 再传给 fromstring(),否则 TypeError: expected str, bytes or os.PathLike object 会立刻教你做人很多 XML 都带着命名空间,尤其 RSS、SOAP、Atom 这些老面孔。比如 ,这时候你直接写 root.find("item") 肯定返回 None——因为默认 namespace 是空字符串,而实际节点藏在另一个 namespace 下。这不是 bug,是标准行为,但确实容易让人抓狂。
root.tag.split("}", 1)[0][1:] 或者正则 r'xmlns="(.*?)"' 粗略抓一下(不严谨,但多数场景够用)ns = {"rss": "http://purl.org/rss/1.0/"}; root.find("rss:item", ns)root.find(".//item") 直接跳过命名空间——但注意,这是 XPath 的模糊匹配,性能略低,而且可能抓到深层嵌套的同名节点,小心误伤XML 里换行和缩进会被解析成文本节点,所以 elem.text 经常是 "\n " 而不是你期望的内容。这真不是 bug,是标准行为——但坑得人不少。
if elem.text:,改成 if elem.text and elem.text.strip() 才靠谱safe_text(elem): return elem.text.strip() if elem is not None and elem.text else ""Hello world ),text 只覆盖第一个文本片段,后面的得用 elem.itertext() 拼接起来findall() 只查直接子节点,iter() 则深度遍历整棵树——用错场景很容易出事,尤其当结构不确定的时候。
item 都在 channel 下,那就用 root.find("channel").findall("item"),清晰又高效link,用 list(root.iter("link")),但注意它比 findall() 慢 2–3 倍——小 XML 无所谓,但到了万级节点就得留个心眼root.findall(".//item"):写法虽然短,但底层也是递归扫描,性能跟 iter() 差不多,可读性反而更差,没必要解析 XML 最容易卡住的从来不是语法,而是命名空间和空白文本这些隐式行为。一旦遇到 None 或空字符串,先盯住这两点,比重写整个解析逻辑快得多。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8