Python BeautifulSoup可以解析XML吗 BS4使用技巧

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.parserhtml5lib 解析 XML——它们会静默修复语法,导致结构失真(例如把 展开成

基础用法:加载 XML 并提取数据

以一段简单 RSS XML 为例:


  
    My Feed
    
      Post One
      https://example.com/1
    
  

使用 lxml 解析:

from bs4 import BeautifulSoup

with 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 解析器不支持命名空间查询。

常见坑与建议

  • 确保安装了 lxmlpip 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.XMLSchemaxmlschema