Как найти элементы по классам

У меня возникают проблемы при разборе HTML-элементов с атрибутом "class" с помощью Beautifulsoup. Код выглядит так

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs: 
    if (div["class"] == "stylelistrow"):
        print div

Я получаю сообщение об ошибке в той же строке "после" сценария заканчивается.

File "./beautifulcoding.py", line 130, in getlanguage
  if (div["class"] == "stylelistrow"):
File "/usr/local/lib/python2.6/dist-packages/BeautifulSoup.py", line 599, in __getitem__
   return self._getAttrMap()[key]
KeyError: 'class'

Как мне избавиться от этой ошибки?

Ответ 1

Вы можете уточнить свой поиск, чтобы найти только те div с данным классом, используя BS3:

mydivs = soup.findAll("div", {"class": "stylelistrow"})

Ответ 3

Обновление: 2016 В последней версии beautifulsoup метод findAll был переименован в 'найти все'. Ссылка на официальную документацию

Список имен методов изменен

Следовательно, ответ будет

soup.find_all("html_element", class_="your_class_name")

Ответ 4

Прямым способом будет:

soup = BeautifulSoup(sdata)
for each_div in soup.findAll('div',{'class':'stylelist'}):
    print each_div

Убедитесь, что вы взяли корпус findAll, его не findall

Ответ 5

Конкретно для BeautifulSoup 3:

soup.findAll('div',
             {'class': lambda x: x 
                       and 'stylelistrow' in x.split()
             }
            )

Найти все из них:

<div class="stylelistrow">
<div class="stylelistrow button">
<div class="button stylelistrow">

Ответ 6

Как найти элементы по классу

У меня возникают проблемы при разборе html-элементов с атрибутом "class" с помощью Beautifulsoup.

Вы можете легко найти по одному классу, но если вы хотите найти по пересечению двух классов, это немного сложнее,

Из документации (выделение добавлено):

Если вы хотите искать теги, которые соответствуют двум или более классам CSS, вы должны использовать селектор CSS:

css_soup.select("p.strikeout.body")
# [<p class="body strikeout"></p>]

Чтобы было ясно, это выбирает только те теги p, которые являются зачеркнутыми и классом тела.

Чтобы найти пересечение любого из набора классов (не пересечение, а объединение), вы можете дать список аргументу ключевого слова class_ (по состоянию на 4.1.2):

soup = BeautifulSoup(sdata)
class_list = ["stylelistrow"] # can add any other classes to this list.
# will find any divs with any names in class_list:
mydivs = soup.find_all('div', class_=class_list) 

Также обратите внимание, что findAll был переименован из camelCase в более find_all.

Ответ 7

CSS селекторы

одиночный первый матч

soup.select_one('.stylelistrow')

список матчей

soup.select('.stylelistrow')

составной класс (т.е. и еще один класс)

soup.select_one('.stylelistrow.otherclassname')
soup.select('.stylelistrow.otherclassname')

Пробелы в именах составных классов, например class = stylelistrow otherclassname заменяются на ".". Вы можете продолжить добавлять классы.

список классов (ИЛИ - совпадать с тем, что присутствует

soup.select_one('.stylelistrow, .otherclassname')
soup.select('.stylelistrow, .otherclassname')

bs4 4.7.1 +

Определенный класс, чей innerText содержит строку

soup.select_one('.stylelistrow:contains("some string")')
soup.select('.stylelistrow:contains("some string")')

Определенный класс, который имеет определенный дочерний элемент, например Тег a

soup.select_one('.stylelistrow:has(a)')
soup.select('.stylelistrow:has(a)')

Ответ 8

Попробуйте проверить, имеет ли атрибут div сначала атрибут класса, например:

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs:
    if "class" in div:
        if (div["class"]=="stylelistrow"):
            print div

Ответ 9

Это работает для меня, чтобы получить доступ к атрибуту class (на beautifulsoup 4, вопреки тому, что говорится в документации). KeyError возвращает список, который не является словарем.

for hit in soup.findAll(name='span'):
    print hit.contents[1]['class']

Ответ 10

По состоянию на BeautifulSoup 4+,

Если у вас есть одно имя класса, вы можете просто передать имя класса в качестве параметра, например:

mydivs = soup.find_all('div', 'class_name')

Или, если у вас более одного имени класса, просто передайте список имен классов как параметр, например:

mydivs = soup.find_all('div', ['class1', 'class2'])

Ответ 11

Это сработало для меня:

for div in mydivs:
    try:
        clazz = div["class"]
    except KeyError:
        clazz = ""
    if (clazz == "stylelistrow"):
        print div

Ответ 12

следующее сработало для меня

a_tag = soup.find_all("div",class_='full tabpublist')

Ответ 13

Это должно работать:

soup = BeautifulSoup(sdata)
mydivs = soup.findAll('div')
for div in mydivs: 
    if (div.find(class_ == "stylelistrow"):
        print div