2009-06-30 14 views

risposta

159

cgi.escape va bene. Sfugge:

  • < al &lt;
  • >-&gt;
  • & al &amp;

Questo è sufficiente per tutti HTML.

EDIT: Se si dispone di caratteri non-ASCII anche voi volete sfuggire, per l'inclusione in un altro documento codificato che utilizza una codifica diversa, come Craig dice, basta usare:

data.encode('ascii', 'xmlcharrefreplace') 

Non dimentica di decodificare data a unicode prima, usando qualsiasi codifica che è stata codificata.

Tuttavia nella mia esperienza quel tipo di codifica è inutile se si lavora sempre con unicode dall'inizio. Basta codificare alla fine della codifica specificata nell'intestazione del documento (utf-8 per la massima compatibilità).

Esempio:

>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace') 
'&lt;a&gt;b&#225;&lt;/a&gt; 

Degno di nota (grazie Greg) è il più parametri quotecgi.escape prende. Impostandolo su True, cgi.escape sfugge anche caratteri con doppia citazione (") in modo da poter utilizzare il valore risultante in un attributo XML/HTML.

EDIT: Si noti che cgi.escape è stato deprecato in Python 3.2 in favore di html.escape, che fa la stessa tranne che quote default è true.

+7

Il parametro booleano aggiuntivo a cgi.escape deve essere considerato anche per le citazioni di escape quando il testo viene utilizzato nei valori di attributo HTML. –

+0

Solo per essere sicuri: se eseguo tutti i dati non fidati attraverso il 'cgi.funzione di fuga, è sufficiente per proteggere contro tutti gli attacs (noti) XSS? –

+0

@Tomas Sedovic: dipende da dove verrà inserito il testo dopo aver eseguito cgi.escape in esso. Se inserito nel contesto HTML di root, allora sì, sei completamente al sicuro. – nosklo

8

cgi.escape dovrebbe essere utile per evitare l'HTML nel senso limitato di escape dei tag HTML e delle entità dei caratteri.

Ma potrebbe essere necessario prendere in considerazione anche i problemi di codifica: se l'HTML che si desidera citare ha caratteri non ASCII in una particolare codifica, allora si dovrebbe anche fare attenzione a rappresentarli sensibilmente quando si cita. Forse potresti convertirli in entità. Altrimenti dovresti assicurarti che le traduzioni corrette di codifica siano fatte tra l'HTML "sorgente" e la pagina in cui è incorporato, per evitare di corrompere i caratteri non ASCII.

65

In Python 3.2 è stato introdotto un nuovo modulo html, che viene utilizzato per l'escape di caratteri riservati dal markup HTML.

Ha una funzione di escape():

>>> import html 
>>> html.escape('x > 2 && x < 7') 
'x &gt; 2 &amp;&amp; x &lt; 7' 
+4

ATTENZIONE: non utilizzare questo per i valori degli attributi, ha vinto ' t fuga cose come (né cgi.escape). –

6

Se si desidera fuggire HTML in un URL:

Questo probabilmente non è quello che il PO ha voluto (la questione non indicare chiaramente in quale contesto si intende utilizzare l'escaping), ma la libreria nativa di Python urllib ha un metodo per sfuggire alle entità HTML che devono essere incluse in un URL in modo sicuro.

Quanto segue è un esempio:

#!/usr/bin/python 
from urllib import quote 

x = '+<>^&' 
print quote(x) # prints '%2B%3C%3E%5E%26' 

Find docs here

+5

Questo è il tipo di escape errato; stiamo cercando [HTML escape] (http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references), al contrario di [codifica URL] (http://en.wikipedia.org/wiki/URL_Encoding). – Chaosphere2112

+2

Tuttavia, era quello che stavo davvero cercando ;-) – Brad

2

cgi.escape esteso

Questa versione migliora cgi.escape. Conserva anche spazi bianchi e nuove righe. Restituisce una stringa 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'&emsp;').\ 
      replace(u' ', u' &nbsp;') 

ad esempio

>>> escape_html('<foo>\nfoo\t"bar"') 
u'&lt;foo&gt;<br />foo&emsp;&quot;bar&quot;' 
0

Via BeautifulSoup4:

>>> bs4.dammit import EntitySubstitution 
>>> esub = EntitySubstitution() 
>>> esub.substitute_html("r&d") 
'r&amp;d' 
2

Non il modo più semplice, ma comunque semplice. La principale differenza dal modulo cgi.escape: funzionerà ancora correttamente se hai già &amp; nel testo. Come si può vedere dai commenti ad esso:

cgi.escape versione

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("&", "&amp;") # Must be done first! 
    s = s.replace("<", "&lt;") 
    s = s.replace(">", "&gt;") 
    if quote: 
     s = s.replace('"', "&quot;") 
    return s 

regex versione

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 = { 
     '<': '&gt;', 
     '>': '&lt;', 
     '&': '&amp;', 
     '"': '&quot;', # should be escaped in attributes 
     "'": '&#39' # should be escaped in attributes 
    } 
    quote_pattern = re.compile(QUOTE_PATTERN) 
    return re.sub(quote_pattern, lambda x: replace_with[x.group(0)], word) 
4

C'è anche l'eccellente markupsafe package.

>>> from markupsafe import Markup, escape 
>>> escape("<script>alert(document.cookie);</script>") 
Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;') 

Il pacchetto markupsafe è ben progettato, e probabilmente il modo più versatile e Pythonic andare di fuggire, secondo me, perché:

  1. il ritorno (Markup) è una classe derivata da unicode (vale a dire isinstance(escape('str'), unicode) == True
  2. Gestisce correttamente l'input Unicode
  3. funziona in Python (2.6, 2.7, 3.3, e PyPy)
  4. esso rispetta i metodi personalizzati di oggetti (ad es. oggetti con una proprietà __html__) e sovraccarichi modello (__html_format__).
Problemi correlati