Я хотел бы перебирать некоторые 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. Любые идеи?
Чтобы соответствовать тексту абзацев под каждым заголовком, я бы попробовал что-то вроде этого (возможно, вам придется изменить это в зависимости от точного формата вывода, который вы хотите):
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']}}
@samplebias: @Lynch прав. Если OP не закрывает свои теги должным образом, они просто не могут ожидать, что синтаксический анализатор сможет читать их мысли.
Попробуйте исправить свой HTML, он, вероятно, будет работать тогда. =)
<p>
не нужно закрывать в HTML, и BeautifulSoup знает, как автоматически их закрывать.