如何在ATOM XML文档中搜索大小写混合的标签名称?

3
我将使用谷歌 API,他们提供返回 JSON 或 ATOM 的选项。ATOM 类似于 XML 语法,我希望使用 BeautifulSoup 来解析它。
我可以轻松地将其转换为 BeautifulSoup 对象,但我很难找到元素。以 ATOM 文档的一段作为示例:
from bs4 import BeautifulSoup

feed = """
<cse:DataObject type="cse_thumbnail">
        <cse:Attribute name="width" value="160"/>
        <cse:Attribute name="height" value="160"/>
        <cse:Attribute name="src" value="https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRAUAShHrU8LK9MLEMEcfg-rtYgLzaxUP-j30lNJJdP1P6FBdVIziH4LTY"/>
</cse:DataObject>
"""

soup = BeautifulSoup(feed)

print soup.find_all("cse:Attribute", {"value":"160"})

返回的是一个空列表,我做错了什么吗?


嗯...非常奇怪。如果我将内部标签名称更改为与原始“Attribute”完全不同的内容,例如<cse:p...>,那么find_all("cse:p", {"value":"160"})就能够返回这些标签。 - har07
在你使用的例子中,@har07 - cse:p - 之所以有效是因为标签名全部小写。更多细节请参见我的回答 - Zero Piraeus
Beautiful Soup是一个HTML解析器,其主要优势在于解析混乱的标签。如果您想解析格式良好的XML,则应该使用XML解析器,例如lxml,而不是滥用HTML解析器来读取XML。 - Lie Ryan
1个回答

1
你的代码按照HTML的方式解析XML,而由于HTML不区分大小写,BeautifulSoup将所有标签名称转换为小写

因为HTML标签和属性不区分大小写, 所有三个HTML解析器都会将标签和属性名称转换为小写。也就是说,标记<TAG></TAG>被转换为<tag></tag>。如果你想保留大小写混合或大写的标签和属性,你需要将文档解析为XML

在搜索小写版本的标记时,效果非常好:
>>> soup.find_all("cse:attribute", {"value":"160"})
[<cse:attribute name="width" value="160"></cse:attribute>, 
 <cse:attribute name="height" value="160"></cse:attribute>]

正如引用的文本所提到的,另一种选择是使用XML解析器,它将保留大小写。然而,使用lxml解析器的BeautifulSoup会从标签名称中剥离命名空间...
>>> soup = BeautifulSoup(feed, "xml")
>>> soup
<?xml version="1.0" encoding="utf-8"?>
<DataObject type="cse_thumbnail">
<Attribute name="width" value="160"/>
<Attribute name="height" value="160"/>
<Attribute name="src" value="https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcRAUAShHrU8LK9MLEMEcfg-rtYgLzaxUP-j30lNJJdP1P6FBdVIziH4LTY"/>
</DataObject>
>>> soup.find_all("cse:Attribute", {"value":"160"})
[]
>>> soup.find_all("cse:attribute", {"value":"160"})
[]
>>> soup.find_all("Attribute", {"value":"160"})
[<Attribute name="width" value="160"/>,
 <Attribute name="height" value="160"/>]

"...这可能不是你想要的。"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接