Как найти теги только с определенными атрибутами - BeautifulSoup
Как бы я, используя BeautifulSoup, искать теги, содержащие ТОЛЬКО атрибуты, которые я ищу?
Например, я хочу найти все теги <td valign="top">
.
Следующий код:
raw_card_data = soup.fetch('td', {'valign':re.compile('top')})
получает все данные, которые я хочу, но также захватывает тег <td>
, который имеет атрибут valign:top
Я также пробовал:
raw_card_data = soup.findAll(re.compile('<td valign="top">'))
и это ничего не возвращает (вероятно, из-за плохого регулярного выражения)
Мне было интересно, есть ли способ в BeautifulSoup сказать "Найти теги <td>
, единственным атрибутом которого является valign:top
"
UPDATE
Например, если HTML-документ содержит следующие теги <td>
:
<td valign="top">.....</td><br />
<td width="580" valign="top">.......</td><br />
<td>.....</td><br />
Мне бы хотелось, чтобы только первый тег <td>
(<td width="580" valign="top">
) возвращал
Ответы
Ответ 1
Как описано в Документация BeutifulSoup
Вы можете использовать это:
soup = BeautifulSoup(html)
results = soup.findAll("td", {"valign" : "top"})
ИЗМЕНИТЬ:
Чтобы вернуть теги, которые имеют только атрибут valign = "top", вы можете проверить длину свойства тега attrs
:
from BeautifulSoup import BeautifulSoup
html = '<td valign="top">.....</td>\
<td width="580" valign="top">.......</td>\
<td>.....</td>'
soup = BeautifulSoup(html)
results = soup.findAll("td", {"valign" : "top"})
for result in results :
if len(result.attrs) == 1 :
print result
Это возвращает:
<td valign="top">.....</td>
Ответ 2
Вы можете использовать функции lambda
в findAll
, как описано в documentation. Чтобы в вашем случае искать тег td
только с valign = "top"
, используйте следующее:
td_tag_list = soup.findAll(
lambda tag:tag.name == "td" and
len(tag.attrs) == 1 and
tag["valign"] == "top")
Ответ 3
если вы хотите искать только имя атрибута с любым значением
from bs4 import BeautifulSoup
import re
soup= BeautifulSoup(html.text,'lxml')
results = soup.findAll("td", {"valign" : re.compile(r".*")})
Ответ 4
Просто передайте его как аргумент findAll
:
>>> from BeautifulSoup import BeautifulSoup
>>> soup = BeautifulSoup("""
... <html>
... <head><title>My Title!</title></head>
... <body><table>
... <tr><td>First!</td>
... <td valign="top">Second!</td></tr>
... </table></body><html>
... """)
>>>
>>> soup.findAll('td')
[<td>First!</td>, <td valign="top">Second!</td>]
>>>
>>> soup.findAll('td', valign='top')
[<td valign="top">Second!</td>]
Ответ 5
Самый простой способ сделать это - использовать новый стиль CSS select
:
soup = BeautifulSoup(html)
results = soup.select('td[valign="top"]')