【问题标题】:problem with selecting a tag in BeautifulSoup在 BeautifulSoup 中选择标签的问题
【发布时间】:2025-01-11 18:35:02
【问题描述】:

我有一个像下面这样的标签,我想用Beautiful Soup 选择它

<td align="right" class="simcal" valign="top"> Title:<br/></td>

当我尝试使用以下代码选择此标签时,一切正常。

# sample 1 :
my_tag = soup.find(
            'td',
            attrs={"align": "right", "class": "header2", "valign": 'top'},
        )
# sample 2 :
my_tag = soup.find(
            text=" Title:",
            attrs={"align": "right", "class": "header2", "valign": 'top'},
        )

但是当我尝试将这两者结合在一起时Beautiful Soup 找不到我想要的元素。

# This will fail
my_tag = soup.find(
            'td',
            text=" Title:",
            attrs={"align": "right", "class": "header2", "valign": 'top'},
        )

所以我的问题是有人可以向我解释这里发生了什么吗?

【问题讨论】:

    标签: python-3.x web-scraping beautifulsoup web-crawler


    【解决方案1】:

    首先,这里有一个错字。你让它在你的 html 中寻找 class="header2" "simcal"

    其次,(这只是我的理解,我不能肯定地说)但是文本" Title:"&lt;br&gt; 标记内,没有属性。所以正确的是它不返回任何具有align="right" class="simcal" valign="top" 属性的东西,因为它属于&lt;td&gt; 标记。这里棘手的是,对于 html,您不需要使用 &lt;br&gt; 标签打开,我认为这就是 BeautifulSoup 在这里被绊倒的原因。

    注意,如果我们删除 &lt;/br&gt; 标签,它会起作用:

    from bs4 import BeautifulSoup
    
    html = '''<td align="right" class="header2" valign="top"> Title:</td>'''
    
    soup = BeautifulSoup(html, 'html.parser')
    my_tag = soup.find(
                'td',
                text=" Title:",
                attrs={"align": "right", "class": "header2", "valign": 'top'},
            )
    
    print(my_tag)
    

    输出:

    <td align="right" class="header2" valign="top"> Title:</td>
    

    要在您的情况下解决此问题,但不必删除关闭的&lt;/br&gt; 标签,并在this solution 的帮助下,我们看到使用'lxml' 解析器而不是'html.parser',它可以处理它。

    from bs4 import BeautifulSoup
    
    html = '''<td align="right" class="header2" valign="top"> Title:</br></td>'''
    
    soup = BeautifulSoup(html, 'lxml')
    
    # sample 1 :
    my_tag1 = soup.find(
                'td',
                attrs={"align": "right", "class": "header2", "valign": 'top'},
            )
    # sample 2 :
    my_tag2 = soup.find(
                text=" Title:",
                attrs={"align": "right", "class": "header2", "valign": 'top'},
            )
    
    my_tag3 = soup.find(
                'td',
                text=" Title:",
                attrs={"align": "right", "class": "header2", "valign": 'top'},
            )
    
    
    
    print(my_tag1)
    print(my_tag2)
    print(my_tag3)
    

    输出:

    <td align="right" class="header2" valign="top"> Title:</td>
    <td align="right" class="header2" valign="top"> Title:</td>
    <td align="right" class="header2" valign="top"> Title:</td>
    

    【讨论】: