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

使用Python3 BeautifulSoup提取XML中d:BANFN遇nth_child_of_type错误求助

解决BeautifulSoup提取XML命名空间标签时的nth_child_of_type错误

嘿,这个问题我之前踩过坑!你碰到的nth_child_of_type错误,其实是因为CSS选择器的语法和XML命名空间前缀冲突导致的——当你写soup.select('d:BANFN')时,BeautifulSoup会把冒号后面的BANFN当成CSS伪类(比如:nth-child这种),但这根本不是有效的伪类,所以直接报错了。咱们来一步步解决:

方案一:用命名空间URL精准查找

你的XML里d:是命名空间前缀,对应的完整命名空间URL是http://schemas.microsoft.com/ado/2007/08/dataservices(从<category>标签的scheme属性能看出来)。BeautifulSoup支持用{命名空间URL}标签名的格式来查找带命名空间的标签,代码示例如下:

from bs4 import BeautifulSoup

# 你的XML内容
xml_data = """<?xml version="1.0" encoding="utf-8"?> 
<entry>
<title type="text">MATERIALSET('R100100100')</title> 
<updated>2018-05-11T04:28:47Z</updated> 
<category term="ZPOC_BOT_PUR_GRP_SRV.MATERIAL" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme"/> 
<link href="MATERIALSET('R100100100')" rel="self" title="MATERIAL"/> 
<content type="application/xml"> 
<m:properties> 
<d:MATNR>R100100100</d:MATNR> 
<d:WERKS>Z100</d:WERKS> 
<d:MENGE> 1.000</d:MENGE> 
<d:EEIND>29.06.2018</d:EEIND> 
<d:BANFN>5000000041</d:BANFN> 
</m:properties> 
</content> 
</entry>"""

# 用lxml-xml解析器处理XML(比默认解析器更适合XML场景)
soup = BeautifulSoup(xml_data, 'lxml-xml')

# 指定d前缀对应的命名空间URL
d_namespace = 'http://schemas.microsoft.com/ado/2007/08/dataservices'
banfn_tag = soup.find(f'{{{d_namespace}}}BANFN')

# 提取并打印结果
if banfn_tag:
    banfn_value = banfn_tag.get_text(strip=True)
    print(f"提取到的BANFN值:{banfn_value}")
else:
    print("未找到BANFN节点")

方案二:用属性选择器绕过命名空间冲突

如果你不想手动写命名空间URL,也可以用CSS属性选择器匹配完整的标签名(避开冒号被当成伪类的问题),代码更简洁:

# 用select_one匹配name属性为d:BANFN的标签
banfn_tag = soup.select_one('[name="d:BANFN"]')

if banfn_tag:
    banfn_value = banfn_tag.get_text(strip=True)
    print(f"提取到的BANFN值:{banfn_value}")

进阶优化:缩小查找范围

为了避免匹配到其他位置的同名标签,你可以先定位到<m:properties>节点,再在里面查找BANFN:

# 先找到m:properties节点(m对应的命名空间是metadata的URL)
m_namespace = 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'
properties_tag = soup.find(f'{{{m_namespace}}}properties')

if properties_tag:
    banfn_tag = properties_tag.find(f'{{{d_namespace}}}BANFN')
    # 或者用select_one:banfn_tag = properties_tag.select_one('[name="d:BANFN"]')
    if banfn_tag:
        print(banfn_tag.get_text(strip=True))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:15:38