Как я могу перебирать теги, используя Python?

1

Я хотел бы перебирать некоторые html и хранить данные в словаре. Каждая итерация начинается с:

<h1 class="docDisplay" id="docTitle">

У меня есть следующий код:

html = '<html><body><h1 class="docDisplay" id="docTitle">Data1</h1><p>other data<\p><h1 class="docDisplay" id="docTitle">Data2</h1><p>other data2<\p></html>'

soup=BeautifulSoup(html)
newdoc = soup.find('h1', id="docTitle")
title = newdoc.findNext(text=True)
data = title.findAllNext('p',text=True)
data_dict = {}
data_dict[title] = {'data': data}
print data_dict

В настоящий момент выход

{u'Data1': {'data': [u'other data<\\p>', u'Data2', u'other data2<\\p>']}}

Я хотел бы, чтобы результат был:

{u'Data1': {'data': [u'other data<\\p>']}, u'Data2': {'data': [u'other data2<\\p>']}}

Я не могу понять, как начать снова, как только я достиг нового тега h1. Любые идеи?

  • 0
    Вы не закрыли свой </ p> правильно. Вы также не закрываете тег своего тела.
  • 2
    Я думаю, именно поэтому он использует BeautifulSoup.
Показать ещё 2 комментария
Теги:
loops
tags
beautifulsoup

2 ответа

2
Лучший ответ

Чтобы соответствовать тексту абзацев под каждым заголовком, я бы попробовал что-то вроде этого (возможно, вам придется изменить это в зависимости от точного формата вывода, который вы хотите):

    from BeautifulSoup import BeautifulSoup

    html = """ 
    <html>
    <head>
    </head>

    <body>
      <h1 class="docDisplay" id="docTitle">Data1</h1>
      <p>other data</p>
      <p>Another paragraph under the first heading.</p>
      <h1 class="docDisplay" id="docTitle">Data2</h1>
      <p>other data2</p>
      <div><p>This paragraph is NOT a sibling of the header</p></div>
    </body>
    </html>
"""

soup = BeautifulSoup(html)

data_dict = {}
stuff_under_current_heading = []

firstHeader = soup.find('h1', id="docTitle")
for tag in [firstHeader] + firstHeader.findNextSiblings():
    if tag.name == 'h1':
        stuff_under_current_heading = []
        # I chose to strip excess whitespace from the header name:
        data_dict[tag.string.strip()] = {'data': stuff_under_current_heading}
        # Modifying the list modifies the value in the dictionary.
    # Take every <p> tag encountered between here and the next heading
    # and associate it with the most recently-seen <h1> tag.
    elif tag.name == 'p':
        stuff_under_current_heading.append(tag.string)
    # Include <p> tags that are not siblings of the <h1> tag but
    # are still part of the content under the header.
    else:
        stuff_under_current_heading.extend(tag.findAll('p', text=True))

print data_dict

Выводит

{u'Data1': {'data': [u'other data', u'Another paragraph under the first heading.']},   
 u'Data2': {'data': [u'other data2', u'This paragraph is NOT a sibling of the header']}}
  • 0
    Спасибо, Джош. Это потрясающе.
-2

@samplebias: @Lynch прав. Если OP не закрывает свои теги должным образом, они просто не могут ожидать, что синтаксический анализатор сможет читать их мысли.

Попробуйте исправить свой HTML, он, вероятно, будет работать тогда. =)

  • 0
    На самом деле теги <p> не нужно закрывать в HTML, и BeautifulSoup знает, как автоматически их закрывать.
  • 0
    Я знаю это. Я говорю, что если ваши HTML-теги не будут правильно структурированы, вы не получите желаемых результатов! Программа не может читать ваши мысли!
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню