【问题标题】:Find different elements according to different criteria using BeautifulSoup in Python在 Python 中使用 BeautifulSoup 根据不同的条件查找不同的元素
【发布时间】:2023-03-19 20:40:01
【问题描述】:

我想使用Beautiful Soup Python 库的findAll() 函数,在HTML 中查找多个元素。这些元素必须满足多个标准,但独立。

例如,假设我的对象如下所示:

<div class="my_class">
    <span class="not_cool">
        <p name="p_1">A</p>
        <p name="p_2">B</p>
    </span>
    <span class="cool">
        <p name="p_3">C</p>
    </span>
</div>

我想找到class="cool" 中的每一个span 以及name="p_1" 中的每一个p(这里只有一个,但想象一下,情况并非如此)。

我会做的:

.findAll("span",attrs={"class":"cool"})
.findAll("p",attrs={"name":"p_1"})

在一个完美的世界里,我想做:

.findAll([
        ["span",attrs={"class":"cool"}],
        ["p",attrs={"name":"p_1"}]
    ]}

当然,它不是这样工作的。

实际上,我尝试制作一个将 HTML 转换为 BBCode 的函数(我不想要也不能使用现有的函数)。 所以,我只需要保留一些我感兴趣的标签。

但是,我还必须知道这些元素的顺序。如果我使用两个不同的.findAll(),我将不知道在什么之前是什么,在什么之后是什么。

请问有人有解决办法吗?

【问题讨论】:

    标签: python html parsing html-parsing beautifulsoup


    【解决方案1】:

    您必须使用搜索功能:

    .find_all(lambda t: (t.name == 'span' and 'cool' in t['class']) or
                        (t.name == 'p' and t.get('name') == 'p_1'))
    

    一个可调用的参数将被传递给树中的每个标签对象;如果可调用返回 True 它被包括在内。上面的lambda 测试标签名称是否匹配以及是否存在特定属性。 class 属性的特殊之处在于,当它出现时,它总是被解析为一个列表。

    请注意,对于 BeautifulSoup 4,驼峰式函数名称已被弃用; lower_case_with_underscore 名称是规范方法。如果您仍在使用 BeautifulSoup 3,您可能需要升级。版本 3 已经 2 年多没有更新了。

    【讨论】:

    • @That1Guy:是的,BeautifulSoup 3 还支持可调用的搜索。
    • @That1Guy:但是,要知道 BeatifulSoup 3 已经 long 过时了。它已经超过 2 年没有看到新版本了。
    • 是的,我意识到这一点。我只是问,因为看起来 OP 正在使用 BeautifulSoup 3(findAll vs find_all)。
    • @That1Guy:BeautifulSoup 4 也支持 BS3 驼峰式方法,很多教程出于某种原因仍然使用这些方法,所以不能假设。
    • 我没有意识到这一点,感谢您的更正。无论如何+1。您的答案比我的更正确,但是对于首选迭代的情况,我将保留我的答案。
    【解决方案2】:

    通过遍历所有需要的spans,只需找到每个span 的所有子级与该特定类。

    spans = soup.findAll("span",attrs={"class":"cool"})
    for span in spans:
        ps = span.findAll("p",attrs={"name":"p_1"})
    

    【讨论】:

    • 我的例子可能并不完美。假设pspan之外,我还想得到它,你的代码就不行了。
    猜你喜欢
    • 2012-04-11
    • 2020-04-26
    • 1970-01-01
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多