gpt4 book ai didi

python - BeautifulSoup find_all() 方法正在抓取比过滤器指定的标签更多的标签

转载 作者:行者123 更新时间:2023-12-01 01:00:18 26 4
gpt4 key购买 nike

我有以下 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> http://some-imageurl.com
</image:loc>
<image:title>GIFTS</image:title>
<image:caption>quirky caption</image:caption>
</image:image>
</url>

我正在尝试仅提取“loc”标签。

我使用了以下代码来执行此操作 products_list = soup.find_all(lambda tag: tag.name == "loc")我尝试过使用 soup.find_all(re.compile("\\bloc\\b"))然而,当我返回此数组结果时,结果中包含 loc 标签和 image:loc 标签(当然还有这些标签文本)。有谁知道即使我指定我想要一个精确的字符串, BeautifulSoup 也会抓取 image:loc ?

最佳答案

假设您使用的是 Beautiful Soup 4.7+。

您实际上可以使用选择器来定位此目标。您显示的内容看起来是 XML,因此我假设您的文档 image 中的某个位置定义了命名空间。对于此示例,我们假设 namespace 定义为 xmlns:image="http://somenamespace.com",这意味着 image 前缀(什么位于 : 之前)表示 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有一个没有分配前缀的命名空间,我们仍然可以定位它。我们假设它的默认命名空间为 xmlns="http://default.com"。我们想要的 loc 没有分配前缀,因此在本例中,它将继承我们的默认命名空间。

文档中的前缀仅对解析器真正重要,因此我们可以为目标命名空间提供任意前缀名称以供选择器使用,我们将其称为default。然后我们可以使用 default|loc 定位 loc 标记。

from bs4 import BeautifulSoup
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://default.com" 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('default|loc', namespaces={'default': 'http://default.com'}))

输出

[<loc>https://mystore.com/products-t-shirt.xml</loc>]    

您甚至可以将其定义为不带前缀的默认命名空间,然后将其定位为 loc:

from bs4 import BeautifulSoup
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://default.com" 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', namespaces={'': 'http://default.com'}))

输出

[<loc>https://mystore.com/products-t-shirt.xml</loc>]    
<小时/>

对于那些不想使用选择器的人,您还可以检查元素的前缀。在本例中,我们需要不带前缀的 loc:

from bs4 import BeautifulSoup
import re
xml = """
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="http://default.com" 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([el for el in soup.find_all('loc') if not el.prefix])

关于python - BeautifulSoup find_all() 方法正在抓取比过滤器指定的标签更多的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55858239/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com