在 BeautifulSoup 中选择标签时出现问题

problem with selecting a tag in BeautifulSoup

我有一个像下面这样的标签,我想 select 它与 Beautiful Soup

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

当我尝试使用以下代码 select 这个标签时一切正常。

# 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'},
        )

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

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

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

注意,如果我们删除 </br> 标签,它会起作用:

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>

为了在您的情况下解决这个问题,但不必删除结束 </br> 标记,并且在 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>