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