BeautifulSoup 支持 XML 解析,但必须显式指定 lxml 或 xml 解析器;默认 html.parser 不适用。推荐 lxml,因其支持命名空间、XPath 和复杂结构;处理带命名空间 XML 需传入 namespaces 参数;注意编码和安装依赖。

可以,但需要正确配置解析器,否则容易报错或解析不全。
支持XML的前提:选择合适的解析器
BeautifulSoup 本身是解析器无关的库,它依赖底层解析器(如 lxml、xml、html.parser)来实际处理文档。默认的 html.parser 只能处理 HTML,无法正确解析 XML 文档(比如带命名空间、自闭合标签、严格语法的 XML)。要解析 XML,必须显式指定支持 XML 的解析器:
- lxml:推荐首选,速度快、功能强,原生支持 XML 和 XPath,能处理命名空间、DOCTYPE、CDATA 等复杂结构
- xml(Python 内置的 xml.etree.ElementTree 的封装):轻量,但功能较弱,不支持 XPath,对格式错误容忍度低
- 避免用 html.parser 或 html5lib 解析 XML——它们会静默修复语法,导致结构失真(例如把
展开成)
基础用法:加载 XML 并提取数据
以一段简单 RSS XML 为例:
My Feed Post One https://example.com/1
使用 lxml 解析:
立即学习“Python免费学习笔记(深入)”;
from bs4 import BeautifulSoupwith open("feed.xml", "r", encoding="utf-8") as f: soup = BeautifulSoup(f, "xml") # 注意这里传入 "xml",等价于 "lxml-xml"
查找所有 item 标签
for item in soup.find_all("item"): title = item.find("title").get_text() link = item.find("link").get_text() print(title, link)
处理带命名空间的 XML
很多标准 XML(如 Atom、SOAP、SVG)使用命名空间,例如:。直接写 soup.find("link") 会找不到。
解决方法是用字典声明命名空间,并在查找时传入:
ns = {"atom": "http://www.w3.org/2005/Atom"}
feed_link = soup.find("atom:link", attrs={"rel": "self"}, namespaces=ns)
if feed_link:
href = feed_link.get("href")注意:namespaces 参数只在 lxml 解析器下生效;xml 解析器不支持命名空间查询。
常见坑与建议
- 确保安装了
lxml:pip install lxml(Windows 用户建议用 pip 安装预编译 wheel,避免编译失败) - XML 文件编码需明确指定(尤其是含中文时),打开文件时加
encoding="utf-8",或用BeautifulSoup(xml_str, "xml", from_encoding="utf-8") - 如果 XML 结构复杂或需高频查询,可先用
soup.find_all()缓存结果,避免重复遍历 - 对严格校验需求(如验证 DTD/XSD),BS4 不适用——应改用
lxml.etree.XMLSchema或xmlschema库










