Krótka wersja!
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)
Źródło Regex: MarkupSafe . Ich wersja obsługuje również encje HTML, podczas gdy ta szybka nie.
Dlaczego nie mogę po prostu usunąć tagów i zostawić go?
To jedna rzecz, aby powstrzymać ludzi przed <i>italicizing</i>
rzeczami, nie pozostawiając i
pływających. Ale to kolejna rzecz, aby wziąć arbitralny wkład i uczynić go całkowicie nieszkodliwym. Większość technik na tej stronie pozostawia niezmienione niezamknięte komentarze ( <!--
) i nawiasy kątowe, które nie są częścią tagów ( blah <<<><blah
). Wersja HTMLParser może nawet pozostawić pełne tagi, jeśli znajdują się w niezamkniętym komentarzu.
Co jeśli twój szablon jest {{ firstname }} {{ lastname }}
? firstname = '<a'
i lastname = 'href="http://evil.com/">'
zostaną przepuszczone przez wszystkie narzędzia do usuwania tagów na tej stronie (z wyjątkiem @Medeiros!), ponieważ same nie są kompletnymi tagami. Usunięcie zwykłych tagów HTML nie wystarczy.
Django strip_tags
, ulepszona (patrz następny nagłówek) wersja najważniejszej odpowiedzi na to pytanie, daje następujące ostrzeżenie:
Absolutnie NIE ma gwarancji, że powstały ciąg będzie bezpieczny w HTML. Dlatego NIGDY nie zaznaczaj bezpiecznie wyniku strip_tags
połączenia bez ucieczki przed nim, na przykład za pomocą escape()
.
Postępuj zgodnie z ich radami!
Aby usunąć tagi za pomocą HTMLParser, musisz uruchomić go wiele razy.
Łatwo jest ominąć najwyższą odpowiedź na to pytanie.
Spójrz na ten ciąg ( źródło i dyskusja ):
<img<!-- --> src=x onerror=alert(1);//><!-- -->
Gdy HTMLParser widzi go po raz pierwszy, nie może stwierdzić, że <img...>
jest to tag. Wygląda na zepsuty, więc HTMLParser się go nie pozbywa. To tylko usuwa <!-- comments -->
, pozostawiając cię z
<img src=x onerror=alert(1);//>
Problem ten został ujawniony projektowi Django w marcu 2014 roku. Ich stary strip_tags
był zasadniczo taki sam jak najlepsza odpowiedź na to pytanie. Ich nowa wersja zasadniczo uruchamia go w pętli, dopóki ponowne uruchomienie nie zmieni łańcucha:
# _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
Oczywiście nic z tego nie stanowi problemu, jeśli zawsze unikniesz wyniku strip_tags()
.
Aktualizacja 19 marca 2015 r . : Wystąpił błąd w wersjach Django przed 1.4.20, 1.6.11, 1.7.7 i 1.8c1. Te wersje mogą wejść w nieskończoną pętlę w funkcji strip_tags (). Naprawiona wersja została odtworzona powyżej. Więcej informacji tutaj .
Dobre rzeczy do skopiowania lub użycia
Mój przykładowy kod nie obsługuje encji HTML - robią to wersje spakowane Django i MarkupSafe.
Mój przykładowy kod został pobrany z doskonałej biblioteki MarkupSafe w celu zapobiegania skryptom krzyżowym. Jest wygodny i szybki (dzięki przyspieszeniom języka C do natywnej wersji Pythona). Jest zawarty w Google App Engine i jest używany przez Jinja2 (wersja 2.7 i nowsze) , Mako, Pylony i inne. Działa łatwo z szablonami Django z Django 1.7.
Strip_tags Django i inne narzędzia HTML z najnowszej wersji są dobre, ale uważam je za mniej wygodne niż MarkupSafe. Są dość samodzielne, możesz skopiować to, czego potrzebujesz z tego pliku .
Jeśli chcesz usunąć prawie wszystkie znaczniki, biblioteka Bleach jest dobra. Możesz wymusić egzekwowanie reguł takich jak „moi użytkownicy mogą pisać kursywą, ale nie mogą tworzyć ramek iframe”.
Poznaj właściwości swojego narzędzia do usuwania tagów! Uruchom na nim testy Fuzz! Oto kod, którego użyłem do badania tej odpowiedzi.
zawstydzona uwaga - samo pytanie dotyczy drukowania na konsoli, ale jest to najlepszy wynik Google dla „python strip html from string”, dlatego właśnie ta odpowiedź dotyczy 99% internetu.
&
.). Możesz albo 1) usunąć je wraz ze znacznikami (często niepożądane i niepotrzebne, ponieważ są one równoważne zwykłemu tekstowi), 2) pozostawić je bez zmian (odpowiednie rozwiązanie, jeśli rozebrany tekst wraca z powrotem do kontekstu HTML) lub 3 ) zdekoduj je do zwykłego tekstu (jeśli rozebrany tekst trafia do bazy danych lub do innego kontekstu innego niż HTML, lub jeśli Twoja platforma internetowa automatycznie wykonuje dla Ciebie znaki ucieczki HTML).