【问题标题】:How can I select an element based on an explicit match in BeautifulSoup?如何根据 BeautifulSoup 中的显式匹配选择元素?
【发布时间】:2020-02-18 17:25:01
【问题描述】:

有两个元素:<div class = "abc def"><div class = "abc">

我想选择后者。

我的代码是

soup.find('div', {'class':'abc'})

但是它选择了前者。

正确的做法是什么?

【问题讨论】:

    标签: python beautifulsoup


    【解决方案1】:

    前一个元素有两个类:和(参见例如How to assign multiple classes to an HTML container?),因此BeautifulSoup 在使用find() 时正确指向它。

    为了指向第二个你应该使用findAll - 它返回一个列表 - 并提取第二个元素:

    soup.findAll('div', {'class':'abc'})[1]
    

    【讨论】:

    • 如果您指的是列表的最后一个元素,您只需输入listname[-1]
    【解决方案2】:

    来自Official doc

    您也可以搜索类属性的确切字符串值

    css_soup.find_all("p", class_="body strikeout")
    # [<p class="body strikeout"></p>]
    
    soup.find_all("div", class_="abc")
    

    【讨论】:

    • 两者都会选择。
    【解决方案3】:

    试试 :nth-of-type(2):nth-child(2) 与 css 选择器。

    print(soup.select_one('.abc:nth-of-type(2)'))
    

    示例

    html='''<div class = "abc def"></div>
            <div class = "abc"></div>'''
    
    soup=BeautifulSoup(html,'html.parser')
    print(soup.select_one('.abc:nth-of-type(2)'))
    

    已编辑:

    print(soup.select_one('.abc:not(.def)'))
    

    【讨论】:

    • 它返回无。
    • @Chan : 请发布您的 html 结构。您的 html 是否看起来像我给定的示例,那么它应该可以工作。如果不是,您可以发布 Html 吗?
    • @Chan :请检查已编辑的答案。希望这会有所帮助。
    • 它仍然返回 None。
    【解决方案4】:

    要获得精确的类匹配,您可以使用以下函数 lambda 表达式作为过滤器。

     soup.find_all(lambda x: x.name == 'div' and ''.join(x.get('class', list())) == 'abc')
    

    如果需要,您也可以将其包装在一个函数中。 ''.join(x.get('class', list())) == 'abc' 加入类(如果可用)并检查它是否等于 'abc'

    例子

    from bs4 import BeautifulSoup
    html = """
    <div class = "abc def"></div>
    <div class = "abc"></div>
    <div></div>
    """
    soup = BeautifulSoup(html, 'html.parser')
    print(
        soup.find_all(
            lambda x: x.name == 'div' and ''.join(x.get('class', list())) == 'abc'
        )
    )
    

    输出

    [<div class="abc"></div>]
    

    参考:

    【讨论】:

      猜你喜欢
      • 2019-10-15
      • 1970-01-01
      • 2020-05-24
      • 2019-08-29
      • 1970-01-01
      • 2021-10-20
      • 1970-01-01
      • 1970-01-01
      • 2020-03-06
      相关资源
      最近更新 更多