Как найти тег без определенного атрибута с помощью BeautifulSoup?

Я пытаюсь получить содержимое тегов «p», у которых нет определенного атрибута.

У меня есть несколько тегов с «классом» = «стоимость» и несколько тегов с «классом» = «стоимость» и «itemrop» = «цена».

all_cars = soup.find_all('div', attrs={'class': 'listdata'})
...
...
tatal_cost= car.findChildren('p', attrs={'class': 'cost'})
cost= car.findChildren('p', attrs={'class': 'cost', 'itemprop':'price'})

Я пытаюсь найти теги «p» без атрибута «itemprop», но не могу найти никакого решения.


person rodahviing    schedule 12.01.2019    source источник


Ответы (2)


BeautifulSoup позволяет определить функцию и передать ее в метод find_all():

def has_class_but_not_itemprop(tag):
    return tag.has_attr('class') and not tag.has_attr('itemprop')

# Pass this function into find_all() and you’ll pick up all the <p> 
# tags you're after:

soup.find_all(has_class_but_not_itemprop)
# [<p class="cost">...</p>,
#  <p class="cost">...</p>,
#  <p class="cost">...</p>]

Дополнительную информацию см. в документации BeautifulSoup.

person chb    schedule 12.01.2019
comment
Я не думаю, что есть какая-то польза от этого, а не от использования soup.find_all('p', attrs={'class': 'cost', 'itemprop':None}) или эквивалентного soup.find_all('p', class_='cost', itemprop=None) — не так ли? (Очевидно, что функция более гибкая, так что к ней можно вернуться, но сопоставление None проще, и эталонные тесты выполняются быстрее, чем функция.) Редактировать: и я только что заметил, что это Ответ Битто Бенничана ниже. - person Trey; 25.03.2021

Для этого достаточно встроенных фильтров атрибутов BeautifulSoup. Вы можете указать True в качестве значения для простой проверки наличия атрибута. None можно использовать, чтобы указать, что атрибут не должен присутствовать. Точно так же значение может быть любым значением атрибута (например, «стоимость»).

from bs4 import BeautifulSoup
html="""
<p class="cost">paragraph 1</p>
<p class="cost">paragraph 2</p>
<p class="cost">paragraph 3</p>
<p class="cost" itemprop="1">paragraph 4</p>
<p class="somethingelse">paragraph 5</p>
"""
soup=BeautifulSoup(html,'html.parser')
print("---without 'itemprop' attribute")
print(soup.find_all('p',itemprop=None))
print("---with class = 'cost' and without 'itemprop' attribute----")
print(soup.find_all('p',attrs={'itemprop':None,"class":'cost'}))
#below is an alternative way to specify this
#print(soup.find_all('p',itemprop=None,class_='cost'))

Выход

---without 'itemprop' attribute
[<p class="cost">paragraph 1</p>, <p class="cost">paragraph 2</p>, <p class="cost">paragraph 3</p>, <p class="somethingelse">paragraph 5</p>]
---with class = 'cost' and without 'itemprop' attribute----
[<p class="cost">paragraph 1</p>, <p class="cost">paragraph 2</p>, <p class="cost">paragraph 3</p>]
person Bitto Bennichan    schedule 12.01.2019