在 BeautifulSoup 中选择标签的问题

Posted

技术标签:

【中文标题】在 BeautifulSoup 中选择标签的问题【英文标题】:problem with selecting a tag in BeautifulSoup 【发布时间】:2022-01-08 02:56:25 【问题描述】:

我有一个像下面这样的标签,我想用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',
        )

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

【问题讨论】:

【参考方案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>

【讨论】:

以上是关于在 BeautifulSoup 中选择标签的问题的主要内容,如果未能解决你的问题,请参考以下文章

在python中用BeautifulSoup选择几个标签项

BeautifulSoup,使用字符串参数递归寻址标签

BeautifulSoup4搜索标签由文本正则表达式

Python3 爬虫U11_BeautifulSoup4之select和CCS选择器提取元素

11-BeautifulSoup库详解

python 极好用的解析 html 标签的模块 - BeautifulSoup