Разработка на коленке

"тут должна быть красивая цитата о программировании"

Получить текст из html, проигнорировав комментарии

2014-04-07 20:30

Нужно взять html и достать из него весь текст, проигнорировав часть тегов, комментарии. При пост-обработке удалить повторяющиеся пробелы. Желательно хотя бы худо-бедно обработать юникод. При этом сохранять оригинальное форматирование необязательно, потому что текст будет обрабатываться машиной, а не показываться человеку.

html5lib тут не особо важен, но он исправляет html, и я указываю его, чтобы избежать проблем с beautifulsoup + mod_wsgi

import bs4
import re

TAGS_TO_REMOVE = ['title', 'head', 'style', 'script']

data = '<b>bold text</b>'

soup = bs4.BeautifulSoup(data, 'html5lib')

# удалить теги с контентом, который не должен попасть в текст
for tag_to_remove in TAGS_TO_REMOVE:
    for el in soup(tag_to_remove):
        el.extract()

# удалить комментарии (в том числе и многострочные),
# тут не стоит пользоваться регулярками, как советуют на некоторых сайтах
# http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454
for comment in soup.findAll(text=lambda text: isinstance(text, bs4.Comment)):
    comment.extract()

# склейка через пробел, чтобы не склеивать два слова в одно,
# тут же html-спецсимволы конвертируются в юникод (&times; - ×)
clean_text = ' '.join(soup.findAll(text=True))

# убрать повторяющиеся пробелы (юникодные в том числе) и пропуски на концах
clean_text = re.sub('(?u)\s+', ' ', clean_text).strip()

print clean_text

В комментариях к коду есть ссылка, где замечательно написано, почему не стоит парсить html при помощи регулярных выражений.