如何在python3中使用BeautifulSoup一次找到多个标签以及属性?

How to find multiple tags at once along with attributes using BeautifulSoup in python3?

提问人:David 提问时间:4/25/2023 最后编辑:M ZDavid 更新时间:4/27/2023 访问量:71

问:

我正在尝试使用 BeautifulSoup 的方法一次找到不同的标签。我找到了一种方法,将所有标签都包含在列表中以获取相应的标签。但是我正在尝试获取标签及其属性。我不确定如何获得它。find_all()

这是引用 HTML 结构。

<html>
    <body>
        <div>
            <h4>Registered Customer Details</h4>
            <div>
                <div class='row'>
                <div class='col-3'>Name :</div>
                <div class='col-6'>ABC</div>
            </div>
            <div>
                <div class='row'>
                <div class='col-3'>Address :</div>
                <div class='col-6'>India</div>
            </div>
            <div class="col-3 col-6 col-12 lo">
                <a class="navbar-brand" href="#">
                    <img alt="image" class="img-responsive" src="/uploads/NEWLOGO.png"/>
                </a>
            </div>
            <h4>Partner Details</h4>
            <div>
                <div class='row'>
                <div class='col-4'>Partners :</div>
                <div class='col-8'><table></table></div>
            </div>
            <div class="span3"></div>
            <div class="span9"></div>
        </div>
    </body>
</html>

我正在尝试立即找到标签。

from bs4 import BeautifulSoup
soup = BeautifulSoup(open('test.html','r').read(),'lxml')
soup.find_all(['h4','div'])

上面的脚本将返回所有 h4 标签和所有 div 标签,但我正在寻找所有 h4 标签和所有 div 标签,其类值为 col-3、col-6、col-4 和 col-8。

它可能看起来像这样,

# for single value
soup.find_all(['h4', ['div',{'class':'col-3'}] ])

# for multiple value
soup.find_all(['h4', ['div',{'class':['col-3','col-6','col-4','col-8']}] ])

输出:

[<h4>Registered Customer Details</h4>, <h4>Partner Details</h4>]

预期输出:

[<h4>Registered Customer Details</h4>,
 <div class='col-3'>Name :</div>,
 <div class='col-6'>ABC</div>,
 <div class='col-3'>Address :</div>,
 <div class='col-6'>India</div>,
 <h4>Partner Details</h4>,
 <div class='col-4'>Partners :</div>,
 <div class='col-8'><table></table>]
html python-3.x beautifulsoup html解析

评论

1赞 Jack Fleeting 4/25/2023
你能编辑你的问题并添加预期的输出吗?
0赞 Jack Fleeting 4/25/2023
那么,例如,不应该在输出中吗?<div class='col-3'>'Key1'</div>
0赞 David 4/25/2023
@JackFleeting 是的,已更新。
1赞 Jack Fleeting 4/25/2023
对不起,但我还是不明白:你对标签感兴趣?你不在乎任何一个?<h4><div>
1赞 HedgeHog 4/26/2023
@David 那么,您能否将输出更新为您期望得到的确切内容,以澄清一下。目前有点困惑。会很棒 - 谢谢

答:

0赞 atinjanki 4/25/2023 #1

试着写这个——

# for single value
soup.find_all(['h4','div'], class_='col-3')

# for multiple value
soup.find_all(['h4','div'], class_=['col-3','col-4'])

评论

0赞 David 4/25/2023
我试过了,但它在输出中缺少 h4 标签,因为 h4 标签没有任何具有匹配值的类。输出:<div class=“col-3”>'Key1'</div> <div class=“col-3”>'Key1'</div> <div class=“col-4”>'Key4'</div>
0赞 atinjanki 4/27/2023
好。我的答案是在您编辑问题并添加预期输出之前写的。在这种情况下,@HedgeHog的答案最好根据您的特定用例进行调整
0赞 HedgeHog 4/27/2023 #2

首先,HTML 应该是有效的,以确保解析器按预期工作。缺少结束标签。

适用于您的示例的一个选项是以下 css 选择器

soup.select('h4,div[class^="col-"]')

如果需要,您可以对其进行调整并使其更具体:

soup.select('h4, div.row  div[class^="col-"]')
...
from bs4 import BeautifulSoup
html = '''<html>
    <body>
        <div>
            <h4>Registered Customer Details</h4>
            <div>
                <div class='row'>
                <div class='col-3'>Name :</div>
                <div class='col-6'>ABC</div>
            </div>
            <div>
                <div class='row'>
                <div class='col-3'>Address :</div>
                <div class='col-6'>India</div>
            </div>
            <h4>Partner Details</h4>
            <div>
                <div class='row'>
                <div class='col-4'>Partners :</div>
                <div class='col-8'><table></table></div>
            </div>
            <div class="span3"></div>
            <div class="span9"></div>
        </div>
    </body>
</html>'''
soup = BeautifulSoup(html,)

soup.select('h4,div[class^="col-"]')
输出
[<h4>Registered Customer Details</h4>,
 <div class="col-3">Name :</div>,
 <div class="col-6">ABC</div>,
 <div class="col-3">Address :</div>,
 <div class="col-6">India</div>,
 <h4>Partner Details</h4>,
 <div class="col-4">Partners :</div>,
 <div class="col-8"><table></table></div>]

评论

0赞 David 4/27/2023
谢谢,几乎得到了所需的输出。我在原始站点 html 中运行了脚本,但是在同一个 div 中具有多个类的类似不需要的“div”标签,就像“col-3 col-4”一样。有没有办法避免这种情况。我已经更新了html结构以供参考。
0赞 HedgeHog 4/27/2023
我很高兴听到它已经帮助过你一次。如前所述,您可以调整该方法并根据您的特定要求进行调整;从我的角度来看,这里列出的选择作为示例正好满足了这一要求。你试过吗?
0赞 David 4/27/2023
是的,我试过了,它在某种程度上起作用,就像传递会给 div 提供 <div class=“col-3”>,<div class=“col-6”>以及 <div class=“col-3 col-6”>。但我专注于 div 将类作为单列。因此,如果我们尝试使用空格,(与 *)或(两者)作为,它什么也没给出,甚至没有一个 div。如果我们将类中的特定 col 硬编码为 ,,或者通过组合来获得它。div[class^="col-"]<div class="col-">div[class^="col- "]div[class^="col-*"]div[class^="col-* "]div[class^="col-3"]div[class^="col-4"]soup.select('h4, div[class^="col-4"],div[class^="col-8"]')
1赞 HedgeHog 4/27/2023
不确定我们是否在谈论相同的内容 - 提到的行正在做您编辑的示例所需的内容。soup.select('h4, div.row div[class^="col-"]')