Укороченная версия!
import re, cgi
tag_re = re.compile(r'(<!--.*?-->|<[^>]*>)')
# Remove well-formed tags, fixing mistakes by legitimate users
no_tags = tag_re.sub('', user_input)
# Clean up anything else by escaping
ready_for_web = cgi.escape(no_tags)
Источник регулярных выражений: MarkupSafe . Их версия также обрабатывает сущности HTML, а эта быстрая - нет.
Почему я не могу просто удалить метки и оставить это?
Одно дело удерживать людей от <i>italicizing</i>
вещей, не оставляя i
парящих вокруг. Но это другой способ принять произвольный вклад и сделать его совершенно безвредным. Большинство методов на этой странице оставят такие вещи, как незакрытые комментарии ( <!--
) и угловые скобки, которые не являются частью тегов (blah <<<><blah
нетронутыми ). Версия HTMLParser может даже оставлять полные теги, если они находятся внутри закрытого комментария.
Что делать, если ваш шаблон {{ firstname }} {{ lastname }}
? firstname = '<a'
и lastname = 'href="http://evil.com/">'
будет пропущен всеми стриптизерами тегов на этой странице (кроме @Medeiros!), потому что они сами по себе не являются полными тегами. Удалять обычные HTML-теги недостаточно.
Django strip_tags
, улучшенная (см. Следующий заголовок) версия главного ответа на этот вопрос, выдает следующее предупреждение:
Абсолютно НЕТ гарантии, что полученная строка безопасна для HTML. Поэтому НИКОГДА не помечайте как безопасный результат strip_tags
вызова, не экранируя его первым, например, с помощью escape()
.
Следуй их советам!
Чтобы удалить теги с HTMLParser, вы должны запустить его несколько раз.
Легко обойти главный ответ на этот вопрос.
Посмотрите на эту строку ( источник и обсуждение ):
<img<!-- --> src=x onerror=alert(1);//><!-- -->
Когда HTMLParser видит его впервые, он не может сказать, что <img...>
это тег. Он выглядит разбитым, поэтому HTMLParser не избавится от него. Это только вынимает <!-- comments -->
, оставляя вас с
<img src=x onerror=alert(1);//>
Эта проблема была раскрыта проекту Django в марте 2014 года. Их старый strip_tags
был по сути тем же, что и главный ответ на этот вопрос. Их новая версия в основном запускает его в цикле, пока повторный запуск не изменит строку:
# _strip_once runs HTMLParser once, pulling out just the text of all the nodes.
def strip_tags(value):
"""Returns the given HTML with all tags stripped."""
# Note: in typical case this loop executes _strip_once once. Loop condition
# is redundant, but helps to reduce number of executions of _strip_once.
while '<' in value and '>' in value:
new_value = _strip_once(value)
if len(new_value) >= len(value):
# _strip_once was not able to detect more tags
break
value = new_value
return value
Конечно, ничто из этого не является проблемой, если вы всегда избегаете результата strip_tags()
.
Обновление 19 марта 2015 : в версиях Django до 1.4.20, 1.6.11, 1.7.7 и 1.8c1 произошла ошибка. Эти версии могут ввести бесконечный цикл в функцию strip_tags (). Фиксированная версия воспроизводится выше. Подробнее здесь .
Хорошие вещи, чтобы скопировать или использовать
Мой пример кода не обрабатывает сущности HTML, как это делают упакованные версии Django и MarkupSafe.
Мой пример кода взят из превосходной библиотеки MarkupSafe для предотвращения межсайтовых скриптов. Это удобно и быстро (с ускорением C до его родной версии Python). Он включен в Google App Engine и используется Jinja2 (2.7 и выше) , Mako, Pylons и другими. Он легко работает с шаблонами Django из Django 1.7.
Django strip_tags и другие html-утилиты из последней версии хороши, но я считаю их менее удобными, чем MarkupSafe. Они довольно автономны, вы можете скопировать то, что вам нужно из этого файла .
Если вам нужно удалить практически все теги, библиотека Bleach подойдет. Вы можете заставить его применять такие правила, как «мои пользователи могут выделять курсивом, но не могут создавать фреймы».
Поймите свойства вашего стриптизерши! Запустите пушистые тесты! Вот код, который я использовал для исследования этого ответа.
зову примечание - сам вопрос касается печати на консоль, но это лучший результат Google для "python strip html from string", поэтому этот ответ на 99% относится к сети.
&
). Вы можете либо 1) удалить их вместе с тегами (часто нежелательно и ненужно, поскольку они эквивалентны простому тексту), 2) оставить их без изменений (подходящее решение, если выделенный текст возвращается обратно в контекст HTML), или 3 ) расшифруйте их в виде обычного текста (если выделенный текст попадает в базу данных или в какой-либо другой контекст, отличный от HTML, или если ваша веб-платформа автоматически выполняет HTML-экранирование текста для вас).