cgi.escape parece una opción posible. Funciona bien? ¿Hay algo que se considere mejor?¿Cuál es la forma más fácil de escanear HTML en Python?
Respuesta
cgi.escape
está bien. Se escapa:
<
a<
>
->
&
a&
Eso es suficiente para que todo el HTML.
EDIT: Si tiene caracteres no ASCII que también quieren escapar, para su inclusión en otro documento codificado que utiliza una codificación diferente, como Craig dice, sólo tiene que utilizar:
data.encode('ascii', 'xmlcharrefreplace')
no hacer
olvide decodificar primero data
a unicode
, usando la codificación que codificó.
Sin embargo, en mi experiencia ese tipo de codificación es inútil si solo trabajas con unicode
todo el tiempo desde el inicio. Simplemente codifique al final la codificación especificada en el encabezado del documento (utf-8
para una compatibilidad máxima).
Ejemplo:
>>> cgi.escape(u'<a>bá</a>').encode('ascii', 'xmlcharrefreplace')
'<a>bá</a>
También digno de mención (gracias Greg) es el parámetro adicional quote
cgi.escape
tomas. Con establecerlo en True
, cgi.escape
también escapa caracteres de comillas dobles ("
) para que pueda usar el valor resultante en un atributo XML/HTML.
EDIT: Tenga en cuenta que cgi.escape ya no se utiliza en Python 3.2 en favor de html.escape
, que hace lo mismo excepto que quote
por defecto a true.
cgi.escape
debe ser bueno para escapar de HTML en el sentido limitado de escapar de las etiquetas HTML y entidades de caracteres.
Pero también debe considerar los problemas de codificación: si el HTML que desea citar tiene caracteres que no son ASCII en una codificación particular, entonces también debe tener cuidado de representarlos con sensatez al citar. Quizás podrías convertirlos en entidades. De lo contrario, debe asegurarse de que las traducciones de codificación correctas se realicen entre el código HTML de "origen" y la página en la que está incrustado, para evitar dañar los caracteres que no sean ASCII.
En Python 3.2 se introdujo un nuevo módulo html
, que se usa para escapar caracteres reservados del marcado HTML.
Tiene una función escape()
:
>>> import html
>>> html.escape('x > 2 && x < 7')
'x > 2 && x < 7'
ADVERTENCIA: no utilice esto para valores de atributos, que ganó' t escape cosas como (ni lo hace cgi.escape). –
¿Qué pasa con 'quote = True'? – 2rs2ts
Si desea escapar de HTML en una dirección URL:
esto probablemente no es lo que el PO quería (la pregunta no indica claramente en en qué contexto se pretende usar el escape), pero la biblioteca nativa de Python urllib tiene un método para escapar de las entidades HTML que deben incluirse en una URL de forma segura.
El siguiente es un ejemplo:
#!/usr/bin/python
from urllib import quote
x = '+<>^&'
print quote(x) # prints '%2B%3C%3E%5E%26'
Este es el tipo incorrecto de escape; estamos buscando escapes [HTML] (http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references), en contraposición a [codificación URL] (http://en.wikipedia.org/wiki/URL_Encoding). – Chaosphere2112
Sin embargo, era lo que realmente estaba buscando ;-) – Brad
cgi.escape
extendieron
Esta versión mejora cgi.escape
. También conserva espacios en blanco y nuevas líneas. Devuelve una cadena 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' ')
por ejemplo
>>> 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'
No es la forma más fácil, pero aún sencillo. La diferencia principal del módulo cgi.escape - aún funcionará correctamente si ya tiene &
en su texto. Como se puede ver a partir de los comentarios a la misma:
cgi.escape versión
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
versión de expresiones regulares
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)
Existe también la excelente markupsafe package.
>>> from markupsafe import Markup, escape
>>> escape("<script>alert(document.cookie);</script>")
Markup(u'<script>alert(document.cookie);</script>')
El paquete markupsafe
está bien diseñado, y probablemente la forma más versátil y Pythonic ir en escapar, en mi humilde opinión, debido a que:
- el retorno (
Markup
) es una clase derivada de Unicode (es decir,isinstance(escape('str'), unicode) == True
- se maneja correctamente la entrada unicode
- funciona en Python (2.6, 2.7, 3.3, y PyPy)
- se respeta los métodos personalizados de objetos (es decir objetos con una propiedad
__html__
) y sobrecargas de plantilla (__html_format__
).
- 1. ¿Cuál es la forma más fácil de animar una línea?
- 2. C#: ¿cuál es la forma más fácil de restar tiempo?
- 3. La forma más fácil de rm -rf en Python
- 4. ¿Cuál es la forma más fácil de convertir el marcado de Wiki a HTML?
- 5. ¿Cuál es la forma más fácil de acceder a un micrófono de una computadora en Python?
- 6. ¿Cuál es la forma más fácil de leer un archivo DBF de FoxPro desde Python?
- 7. ¿Cuál es la forma más fácil y no intensiva de memoria de exportar XML desde Python?
- 8. ¿cuál es la forma más rápida de escanear un archivo muy grande en Java?
- 9. ¿Cuál es la forma más fácil de crear una extensión C opcional para un paquete python?
- 10. ¿Cuál es la forma más fácil de convertir la lista con str en list con int?
- 11. ¿La forma más fácil de convertir una lista en una tabla HTML en python?
- 12. ¿Cuál es la forma más fácil de hacer 'es' en Java?
- 13. ¿Cuál es la forma más simple de usar SSH Python?
- 14. ¿Cuál es la forma más fácil de probar la membresía de clase en coffeescript?
- 15. La forma más fácil de transferir datos por Internet, Python
- 16. ¿Cuál es la forma más fácil de agregar comas a un número entero?
- 17. ¿Cuál es la forma más fácil de hacer la negación en los desencadenantes?
- 18. ¿Cuál es la forma más fácil de probar una API REST de catalizador?
- 19. ¿Cuál es la forma más fácil de mostrar una lista editable (como una hoja de cálculo) en HTML?
- 20. Cuál es la nube más fácil para contenido web estático
- 21. ¿Cuál es la forma más fácil de imprimir texto en pantalla en OpenGL?
- 22. ¿Cuál es la forma más fácil de explicar qué es Hadoop y mapa/reducir?
- 23. ¿Cuál es la forma más fácil de detectar si se ha cambiado al menos un campo en un formulario HTML?
- 24. ¿Cuál es la forma más fácil de dibujar texturas con OpenGL ES?
- 25. ¿Cuál es la forma más fácil de saber si una gramática BNF es ambigua o no?
- 26. ¿Cuál es la forma más fácil de usar el comando HEAD de HTTP en PHP?
- 27. ¿Cuál es la forma más fácil de llenar los vacíos en una lista de números?
- 28. ¿Cuál es la forma más fácil de eliminar todos los atributos de un XML en C#?
- 29. ¿Cuál es la forma más fácil de conservar datos en una aplicación de iPhone?
- 30. ¿Cuál es la forma más fácil de obtener datos espaciales de sql 08 en un mapa?
El parámetro booleano adicional de cgi.escape también se debe tener en cuenta para las comillas de escape cuando se usa texto en los valores de los atributos HTML. –
Solo para estar seguro: si ejecuto todos los datos no confiables a través del 'cgi.función de escape, es suficiente para proteger contra todos los attacs XSS (conocidos) –
@Tomas Sedovic: Depende de dónde coloques el texto después de ejecutar cgi.escape en él. Si se coloca en el contexto HTML raíz, entonces sí, estás completamente seguro. – nosklo