Я не использовал BeautifulSoup, но он должен быть похож на встроенную библиотеку HTMLParser.Это класс, который я создал для анализа входного html и преобразования тегов в требуемую другую «разметку».
<code>class BaseHTMLProcessor(HTMLParser):
def reset(self):
# extend (called by HTMLParser.__init__)
self.pieces = []
HTMLParser.reset(self)
def handle_starttag(self, tag, attrs):
# called for each start tag
# attrs is a list of (attr, value) tuples
# e.g. for <pre class="screen">, tag="pre", attrs=[("class", "screen")]
# Ideally we would like to reconstruct original tag and attributes, but
# we may end up quoting attribute values that weren't quoted in the source
# document, or we may change the type of quotes around the attribute value
# (single to double quotes).
# Note that improperly embedded non-HTML code (like client-side Javascript)
# may be parsed incorrectly by the ancestor, causing runtime script errors.
# All non-HTML code must be enclosed in HTML comment tags (<!-- code -->)
# to ensure that it will pass through this parser unaltered (in handle_comment).
if tag == 'b':
v = r'%b[1]'
elif tag == 'li':
v = r'%f[1]'
elif tag == 'strong':
v = r'%b[1]%i[1]'
elif tag == 'u':
v = r'%u[1]'
elif tag == 'ul':
v = r'%n%'
else:
v = ''
self.pieces.append("{0}".format(v))
def handle_endtag(self, tag):
# called for each end tag, e.g. for
, тег будет «pre» # Восстановить исходный конечный тег.if tag == 'li': v = r '% f [0]' elif tag == '/ b': v = r '% b [0]' elif tag == 'strong': v = r '%b [0]% i [0] 'elif tag ==' u ': v = r'% u [0] 'elif tag ==' ul ': v =' 'elif tag ==' br ': v =r '% n%' else: v = '' # это соответствует, но мы не знаем, что это такое!предположим, что это недопустимый HTML и удалите его self.pieces.append ("{0}". format (v)) def handle_charref (self, ref): # вызывается для каждой ссылки на символ, например, для "", ref будет "160"# Восстановить исходную ссылку на символ.self.pieces.append ("& #% (ref) s;"% locals ()) def handle_entityref (self, ref): # вызывается для каждой ссылки на сущность, например, для "©", ref будет "copy" # Reconstructисходная ссылка на сущность.self.pieces.append ("&% (ref) s"% locals ()) # стандартные объекты HTML закрываются точкой с запятой;другие объекты не выполняются, если htmlentitydefs.entitydefs.has_key (ref): self.pieces.append (";") def handle_data (self, text): # вызывается для каждого блока простого текста, т.е. вне любого тега и # не содержитссылки на любые символы или объекты # Хранить оригинальный текст дословно.output = text.replace ("\ xe2 \ x80 \ x99", "'"). split (' \ r \ n ') для счетчика, элемент в перечислении (вывод): output [count] = item.strip () self.pieces.append (''. join (output)) def handle_comment (self, text): # вызывается для каждого комментария HTML, например# Восстановить исходный комментарий.# Особенно важно, чтобы исходный документ заключал # -кодовый код на стороне клиента (например, Javascript) в комментарии, чтобы он мог беспрепятственно проходить через этот # процессор;смотрите комментарии в unknown_starttag для деталей.self.pieces.append (»"% locals ()) def handle_pi (self, text): # вызывается для каждой инструкции обработки, например# Восстановить оригинальную инструкцию по обработке.self.pieces.append (»"% locals ()) def handle_decl (self, text): # вызывается для DOCTYPE, если присутствует, например #"% locals ()) def output (self):" "" Вернуть обработанный HTML в виде одной строки "" "return" ".join (self.pieces)
Чтобы использовать класс, простоИсходный код. Затем в вашем коде используйте следующие строки:
parser = BaseHTMLProcessor()
for line in input:
parser.feed(line)
parser.close()
output = parser.output()
parser.reset()
print output
Он работает путем токенизации входного потока. Каждый фрагмент HTML, с которым он работает, обрабатывается соответствующим методом. Так что <p><b>This is bold text!</b></p>
вызоветhandle_starttag
дважды, затем handle_data
один раз, затем handle_endtag
дважды.Наконец, когда вызывается метод вывода, он возвращает содержимое потока, объединенное вместе.