Python Beautiful soup find_all()方法获取的标记比筛选器指定的多
我有以下xmlPython Beautiful soup find_all()方法获取的标记比筛选器指定的多,python,beautifulsoup,Python,Beautifulsoup,我有以下xml <url> <loc>https://mystore.com/products-t-shirt.xml</loc> <lastmod>2019-04-11T00:01:42-04:00</lastmod> <changefreq>daily</changefreq> <image:image> <image:loc>
<url>
<loc>https://mystore.com/products-t-shirt.xml</loc>
<lastmod>2019-04-11T00:01:42-04:00</lastmod>
<changefreq>daily</changefreq>
<image:image>
<image:loc> http://some-imageurl.com
</image:loc>
<image:title>GIFTS</image:title>
<image:caption>quirky caption</image:caption>
</image:image>
</url>
https://mystore.com/products-t-shirt.xml
2019-04-11T00:01:42-04:00
每日的
http://some-imageurl.com
礼品
古怪的标题
我正试图提取“loc”标签
我使用了以下代码来实现这一点
products\u list=soup.find\u all(lambda标签:tag.name==“loc”)
我尝试过使用
soup.find_all(re.compile(\\bloc\\b”)
但是当我返回这个数组结果时,结果中有loc标记和image:loc标记(当然还有那些标记文本)。是否有人知道Beauty soup正在抓取image:loc,即使我指定我想要一个精确的字符串?这假设您使用的是Beauty soup 4.7+
实际上,您可以使用选择器来实现这一目标。您显示的内容看起来是XML,所以我假设您的文档image
中的某个地方定义了名称空间。在本例中,我们假设名称空间定义为xmlns:image=”http://somenamespace.com“
表示图像
前缀(在之前的内容:
)表示http://somenamespace.com
名称空间。我们将假设没有名称空间的loc
。最后,我们将使用|loc
指定希望loc
不带命名空间:
from bs4 import BeautifulSoup
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:image="http://somenamespace.com">
<url>
<loc>https://mystore.com/products-t-shirt.xml</loc>
<lastmod>2019-04-11T00:01:42-04:00</lastmod>
<changefreq>daily</changefreq>
<image:image>
<image:loc> http://some-imageurl.com
</image:loc>
<image:title>GIFTS</image:title>
<image:caption>quirky caption</image:caption>
</image:image>
</url>
</root>
"""
soup = BeautifulSoup(xml, 'xml')
print(soup.select('|loc'))
输出
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
输出
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
[<loc>https://mystore.com/products-t-shirt.xml</loc>]
我尝试了这个设置,我的输出是:
[https://mystore.com/products-t-shirt.xml]
首先,我加载一个包含字符串的文件。然而,我不得不做出一些更正:
文件:test.xml
<?xml version="1.0" encoding="UTF-8"?>
<url xmlns:image=" ">
<loc>https://mystore.com/products-t-shirt.xml</loc>
<lastmod>2019 - 04 - 11
T00: 01:42 - 04: 00
</lastmod>
<changefreq>daily</changefreq>
<image: image="">
<image loc="">http://some-imageurl.com
</image>
<image: title="">GIFTS</image:>
<image: caption="">quirky caption</image:>
</image:>
</url>
正如您在输出中看到的,检索到的唯一字符串是loc标记only
我希望它能帮上忙谢谢你的回答,但不幸的是,我已经尝试过了,而且还没有成功,我的答案确实是基于你的代码;完全不同的是xml本身。在我的IDE中,它似乎充满了错误。您可以通过导入xml部分并应用一些str()来解决这个问题。例如:str(xml\u text).replace(“:image”,“:image=\”)。希望对你有帮助。然而,另一个答案(我没有测试过)在阅读时似乎是正确的和有用的。我有一个与朋友的预定会议要参加,但我回家后会进一步研究另一个解决方案。我尝试了他/她在上次建议中展示的内容,但我收到了一个空数组,因此没有匹配项。其代码类似于此product_list=soup.select('loc',namespaces={'':''}),其中还有一个http://文件。所以我只是不想表明它还没有工作,我还在想为什么.select()可以在xml上工作,但我会继续探索您的解决方案。据我所见,select()使用的是soup sieve库,它似乎是一个css选择器库。我的命名空间也是,没有一个URL包含该域。我只是在互联网上仔细阅读了一下,发现你的github上有soup sieve文档。我尝试使用|*强制使用默认名称空间,但仍然没有成功。至少我现在理解了整个xml名称空间问题和推理,因为CSS选择器可以应用于其他文档类型。并不是所有的东西都能真正转换成XML,比如特定于HTML的伪类,但并没有什么能阻止它们工作。另外,请记住,XHTML是XML和HTML,选择器也在其中工作。名称空间也被带入了HTML5中,尽管通常没有前缀和暗示。是的,soup sieve就是这个库,我是它的作者。我更新了一个替代解决方案,它不使用选择器,只需查看
find\u all
中返回的元素,并检查没有前缀的元素。
import bs4 as BS
if __name__ == "__main__":
with open("test.xml", "r") as f:
xml = f.read()
soup = BS.BeautifulSoup(xml, "lxml")
tag_selection = soup.find_all(lambda tag: tag.name == "loc")
print(tag_selection)