BeautifulSoup — помоги мне выбрать divs и классы

#python #html #json #beautifulsoup

#python #HTML #json #beautifulsoup

Вопрос:

Вот мой код HMTL:

 <div class="BlockA">
    <h4>BlockA</h4>
    <div class="name">John Smith</div>
    <div class="number">2</div>
    <div class="name">Paul Peterson</div>
    <div class="number">14</div>
</div>

<div class="BlockB">
    <h4>BlockB</h4>
    <div class="name">Steve Jones</div>
    <div class="number">5</div>
</div>
  

Обратите внимание на BlockA и BlockB . Оба содержат одинаковые элементы, т.е. name и number , но находятся внутри отдельных классов. Я новичок в python и думал попробовать что-то вроде:

 parsedHTML = soup.findAll("div", attrs={"name" : "number"})
  

но это просто дает мне пустой экран. Возможно ли для меня сделать findAll изнутри blockA , отобразить данные, затем запустить другой цикл из BlockB и сделать то же самое?

Спасибо.

РЕДАКТИРОВАТЬ: Для тех, кто спрашивает, я хочу просто перебирать значения и вывод в JSON следующим образом:

 BlockA
    John Smith
    2
    Paul Peterson
    14

BlockB
    Steve Whoever
    123
    Mr Whathisface
    23
  

Комментарии:

1. Вы не сказали нам, что вы хотите сделать! 😉

2. Что вы хотите с помощью attrs={«name»: «number»}???? Возможно, вы хотите внимательно прочитать BeautifulSoup (!) и использовать {‘class’: ‘number’} или что-то еще….

Ответ №1:

Вы хотите найти divs, которые содержат атрибут класса «name» или «number»?

 >>> import re
>>> soup.findAll("div", {"class":re.compile("name|number")})

[<div class="name">John Smith</div>, <div class="number">2</div>, <div class="name">Paul Peterson</div>, <div class="number">14</div>, <div class="name">Steve Jones</div>, <div class="number">5</div>]
  

Ответ №2:

Вам нужно использовать список возможных class значений.

 soup.findAll('div', {'class': ['name', 'number']})
  

После просмотра вашей правки:

 def grab_content(heading):
    siblings = [s.contents[0] for s in heading.findNextSiblings()]
    return {heading.contents[0]: siblings}

headings = soup.findAll('h4')
[grab_content(h) for h in headings]
  

И вывод для вашего исходного HTML-фрагмента будет:

 [{u'BlockA': [u'John Smith', u'2', u'Paul Peterson', u'14']},
 {u'BlockB': [u'Steve Jones', u'5']}]
  

Комментарии:

1. Спасибо за ответ. Если я выполняю a, finadAll(h4) которое просто возвращает BlockB при выводе в конце, используя return HttpResponse(h) и return HttpResponse(h.content) возвращает none. Я чего-то не понимаю?