cgi.escape wydaje się być jednym z możliwych wyborów. Czy to działa dobrze? Czy jest coś, co uważa się za lepsze?Jaki jest najprostszy sposób na uniknięcie HTML w Pythonie?
Odpowiedz
cgi.escape
jest w porządku. Ucieka:
<
do<
>
do>
&
do&
to wystarczy dla wszystkich HTML.
EDIT: Jeśli masz non-ASCII znaki również chcesz uciec, do włączenia do innego zakodowanego dokumentu, który używa innego kodowania, jak Craig mówi, wystarczy użyć:
data.encode('ascii', 'xmlcharrefreplace')
Nie zapomnij najpierw rozkodować data
na unicode
, używając dowolnego kodowania, które zostało zakodowane.
Jednak z mojego doświadczenia wynika, że takie kodowanie jest bezużyteczne, jeśli po prostu pracujesz z unicode
przez cały czas od rozpoczęcia. Po prostu zakoduj kodowanie określone w nagłówku dokumentu (utf-8
, aby uzyskać maksymalną zgodność).
Przykład:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
Warto również zauważyć (dzięki Greg) jest dodatkowy parametr quote
cgi.escape
trwa. Dzięki niemu ustawiona na True
, cgi.escape
powoduje również uniknięcie podwójnego cudzysłowu ("
), aby można było użyć wartości wynikowej w atrybucie XML/HTML.
EDIT: Zauważ, że cgi.escape została zaniechana w Pythonie 3.2 na rzecz html.escape
, który robi to samo z tym że quote
domyślnych true.
cgi.escape
powinno być dobre, aby uciec z HTML w ograniczonym sensie ucieczki z tagów HTML i encji znakowych.
Ale może być również konieczne rozważenie problemów z kodowaniem: jeśli kod HTML, który chcesz zacytować, zawiera znaki spoza zestawu ASCII w określonym kodowaniu, musisz również zadbać o to, aby były one rozsądnie reprezentowane podczas cytowania. Być może mógłbyś przekonwertować je na podmioty. W przeciwnym razie należy upewnić się, że wykonywane są odpowiednie tłumaczenia kodowania między "źródłowym" kodem HTML i stroną, na której jest osadzony, aby uniknąć uszkodzenia znaków spoza ASCII.
W Pythonie 3.2 wprowadzono nowy moduł html
, który służy do usuwania znaków zastrzeżonych ze znaczników HTML.
Posiada jedną funkcję escape()
:
>>> import html
>>> html.escape('x > 2 && x < 7')
'x > 2 && x < 7'
OSTRZEŻENIE: Nie używaj tego dla wartości atrybutów, wygrał ' t uciekaj od rzeczy takich jak (ani cgi.escape). –
Co z 'quote = True'? – 2rs2ts
Jeśli chcesz uciec HTML w adresie URL:
to prawdopodobnie nie jest to, co chciał OP (kwestia nie należy wyraźnie wskazać w z którego kontekstu ma korzystać escaping), ale natywna biblioteka Pythona urllib ma metodę unikania encji HTML, które muszą być bezpiecznie zawarte w adresie URL.
Poniższy przykład:
#!/usr/bin/python
from urllib import quote
x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'
To jest niewłaściwy rodzaj ucieczki; szukamy [ucieczki HTML] (http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references), w przeciwieństwie do [kodowania URL] (http://en.wikipedia.org/wiki/URL_Encoding). – Chaosphere2112
Mimo to - właśnie tego szukałem ;-) – Brad
cgi.escape
przedłużony
Wersja ta poprawia cgi.escape
. Zachowuje również białe spacje i znaki nowej linii. Zwraca ciąg znaków unicode
.
def escape_html(text):
"""escape strings for display in HTML"""
return cgi.escape(text, quote=True).\
replace(u'\n', u'<br />').\
replace(u'\t', u' ').\
replace(u' ', u' ')
np
>>> escape_html('<foo>\nfoo\t"bar"')
u'<foo><br />foo "bar"'
Via BeautifulSoup4:
>>> bs4.dammit import EntitySubstitution
>>> esub = EntitySubstitution()
>>> esub.substitute_html("r&d")
'r&d'
Nie najprostszy sposób, ale nadal proste. Główna różnica od modułu cgi.escape - nadal będzie działać poprawnie, jeśli masz już w swoim tekście &
. Jak widać z komentarzy do niego:
cgi.escape wersja
def escape(s, quote=None):
'''Replace special characters "&", "<" and ">" to HTML-safe sequences.
If the optional flag quote is true, the quotation mark character (")
is also translated.'''
s = s.replace("&", "&") # Must be done first!
s = s.replace("<", "<")
s = s.replace(">", ">")
if quote:
s = s.replace('"', """)
return s
regex wersja
QUOTE_PATTERN = r"""([&<>"'])(?!(amp|lt|gt|quot|#39);)"""
def escape(word):
"""
Replaces special characters <>&"' to HTML-safe sequences.
With attention to already escaped characters.
"""
replace_with = {
'<': '>',
'>': '<',
'&': '&',
'"': '"', # should be escaped in attributes
"'": ''' # should be escaped in attributes
}
quote_pattern = re.compile(QUOTE_PATTERN)
return re.sub(quote_pattern, lambda x: replace_with[x.group(0)], word)
Istnieje również doskonałe markupsafe package.
>>> from markupsafe import Markup, escape
>>> escape("<script>alert(document.cookie);</script>")
Markup(u'<script>alert(document.cookie);</script>')
Pakiet markupsafe
jest dobrze zaprojektowane, i prawdopodobnie najbardziej wszechstronny i pythonic droga o ucieczce, IMHO, ponieważ:
- powrót (
Markup
) to klasa pochodzi z unicode (czyliisinstance(escape('str'), unicode) == True
- to poprawnie obsługuje wejście unicode
- działa w Pythonie (2.6, 2.7, 3.3 i pypy)
- to respektuje niestandardowe metody obiektów (tj. obiekty o właściwościach
__html__
) i przeciążenia szablonów (__html_format__
).
- 1. Jaki jest najprostszy międzyplatformowy sposób wyświetlania okien dialogowych w Pythonie?
- 2. Jaki jest najlepszy sposób na uniknięcie wyjątku NoSuchElementException w Selenie?
- 3. Sposób na uniknięcie histogramu?
- 4. Jaki jest najprostszy sposób na iterację w tablicy tablic?
- 5. Jaki jest najprostszy sposób na stworzenie ukształtowanego okna w wxPythonie?
- 6. Jaki jest najprostszy sposób na utrzymanie map/struktur w Clojure?
- 7. Jaki jest najprostszy sposób zapisu na stdout w trybie binarnym?
- 8. Jaki jest najprostszy sposób na konwersję zrzutu danych SO z HTML z powrotem na Markdown?
- 9. Jaki jest najprostszy sposób na aktualizację schematu mnesii?
- 10. Jaki jest najprostszy sposób na zbudowanie strony z rezerwacją spotkania?
- 11. Jaki jest najprostszy sposób na usunięcie pustych NSStrings z NSArray?
- 12. Jaki jest najprostszy sposób wyczyszczenia wszystkich pseudo klas na elemencie?
- 13. Dobry sposób na uniknięcie "udostępniania"?
- 14. Jaki jest najprostszy sposób zdefiniowania zmiennej lokalnej w Oracle?
- 15. Jaki jest najbardziej elegancki sposób zapisu tej pętli w Pythonie?
- 16. Jaki jest najprostszy sposób utworzenia pustej iteracji przy użyciu wydajności w Pythonie?
- 17. Jaki jest najprostszy sposób utworzenia żądania HTTP GET w Perlu?
- 18. Jaki jest najprostszy sposób użycia szablonów widoku wąsów w szynach?
- 19. Jaki jest najprostszy sposób, aby obraz był dotykalny w libgdx?
- 20. W Chrome, jaki jest najprostszy sposób wyświetlenia typu MIME dokumentu?
- 21. Clojure: Idiomatyczny/czysty sposób na uniknięcie NPE w monadowy sposób
- 22. Jaki jest najlepszy sposób na zastąpienie operatora trójskładnikowego w Pythonie?
- 23. Jaki jest najbardziej efektywny sposób na iterowanie listy w pythonie?
- 24. Jaki jest najlepszy sposób na uniknięcie próby ... złapania ... w końcu ... w moich testach jednostkowych?
- 25. Najprostszy sposób na pobranie pliku?
- 26. Jaki jest najlepszy sposób na uniknięcie znaków niesformatowanych w to_char Oracle?
- 27. Najprostszy sposób na wymuszenie awarii w Swift
- 28. Jaki jest najprostszy sposób obsługi zdarzenia SelectedItem z MVVM?
- 29. Czy istnieje sposób na uniknięcie wyszukiwania liniowego?
- 30. Jaki jest najprostszy sposób wykonania klasy Java co 30 sekund?
Dodatkowy parametr boolowski dla cgi.escape powinien również być brany pod uwagę przy wycofywaniu cudzysłowu, gdy tekst jest używany w wartościach atrybutów HTML. –
Tylko dla pewności: Jeśli uruchomię wszystkie niezaufane dane przez 'cgi.funkcja ucieczki, wystarcza, aby chronić przed wszystkimi (znanymi) attacami XSS? –
@ Tomas Sedovic: Zależy od tego, gdzie umieścisz tekst po uruchomieniu cgi.escape w nim. Jeśli jest umieszczony w głównym kontekście HTML, to tak, jesteś całkowicie bezpieczny. – nosklo