You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3+Beautiful Soup 4解析XML命名空间:为何部分代码失效?

问题:BS4解析XML时命名空间解析异常,第一段代码正常运行第二段不行

我正尝试使用Python 3中的BS4解析XML,但无法解析命名空间。参考相关问题后仍未解决,且无报错信息。为何第一段代码可正常运行,第二段却不行?

import requests
from bs4 import BeautifulSoup

input = """
<?xml version="1.0" encoding="utf-8"?>
<wb:countries page="1" pages="6" per_page="50" total="299" xmlns:wb="http://www.worldbank.org">
  <wb:country id="ABW">
    <wb:iso2Code>AW</wb:iso2Code>
    <wb:name>Aruba</wb:name>
    <wb:region id="LCN" iso2code="ZJ">Latin America &amp; Caribbean </wb:region>
    <wb:adminregion id="" iso2code="" />
    <wb:incomeLevel id="HIC" iso2code="XD">High income</wb:incomeLevel>
    <wb:lendingType id="LNX" iso2code="XX">Not classified</wb:lendingType>
    <wb:capitalCity>Oranjestad</wb:capitalCity>
    <wb:longitude>-70.0167</wb:longitude>
    <wb:latitude>12.5167</wb:latitude>
  </wb:country>
  <wb:country id="AFE">
    <wb:iso2Code>ZH</wb:iso2Code>
    <wb:name>Africa Eastern and Southern</wb:name>
    <wb:region id="NA" iso2code="NA">Aggregates</wb:region>
    <wb:adminregion id="" iso2code="" />
    <wb:incomeLevel id="NA" iso2code="NA">Aggregates</wb:incomeLevel>
    <wb:lendingType id="" iso2code="">Aggregates</wb:lendingType>
    <wb:capitalCity />
    <wb:longitude />
    <wb:latitude />
  </wb:country>
</wb:countries>

<item>
  <title>Some string</title>
  <pubDate>Wed, 01 Sep 2022 12:45:00 +0000</pubDate>
  <guid isPermaLink="false">4574785</guid>
  <link>https://somesite.com</link>
  <itunes:subtitle>A subtitle</itunes:subtitle>
  <enclosure length="0" type="audio/mpeg" url="https://assets.somesite.com/123.mp3"/>
  <itunes:image href="https://somesite.com/img.jpg"/>
  <itunes:duration>7845</itunes:duration>
  <itunes:explicit>no</itunes:explicit>
  <itunes:episodeType>Full</itunes:episodeType>
</item>
"""

soup = BeautifulSoup(input, 'xml')

# Working
for x in soup.find_all('wb:country'):
    print(x.find('wb:name').text)

# Not working
for x in soup.find_all('item'):
    print(x.find('itunes:subtitle').text)

问题原因

两段代码的核心差异在于命名空间是否被正确声明:

  • 第一段的wb:前缀在根节点<wb:countries>中通过xmlns:wb="http://www.worldbank.org"做了正式声明,BS4的XML解析器能识别这个命名空间,因此wb:country、wb:name可以被正常匹配。
  • 第二段的itunes:前缀没有在XML中做任何声明,解析器无法识别这个命名空间,会把itunes:subtitle当作包含冒号的普通标签名,但BS4处理命名空间时,实际会将标签名拆分为「命名空间URI」和「本地名」,直接用itunes:subtitle查找会匹配失败。

解决方法

方法1:补全命名空间声明

给<item>标签添加itunes的标准命名空间声明,修改后的<item>标签如下:

<item xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">

此时原代码中的x.find('itunes:subtitle')就能正常匹配。

方法2:使用命名空间URI查找

直接通过itunes的标准命名空间URI来定位标签,无需修改XML内容:

# 修改后的第二段代码
for x in soup.find_all('item'):
    # 用itunes的命名空间URI拼接标签名
    print(x.find('{http://www.itunes.com/dtds/podcast-1.0.dtd}subtitle').text)

方法3:通过标签名模糊匹配

如果不确定命名空间URI,也可以用lambda函数匹配包含冒号的标签名:

# 修改后的第二段代码
for x in soup.find_all('item'):
    print(x.find(lambda tag: tag.name == 'itunes:subtitle').text)

内容的提问来源于stack exchange,提问作者Arete

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:40:31