tutorial tag read parser parsear python html

tag - ¿Cuál es la forma más fácil de escanear HTML en Python?



read html file python (9)

cgi.escape parece ser una posible elección. Funciona bien? ¿Hay algo que se considere mejor?


cgi.escape extended

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''&emsp;'')./ replace(u'' '', u'' &nbsp;'')

por ejemplo

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


A través de BeautifulSoup4 :

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


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 &gt; 2 &amp;&amp; x &lt; 7''


Ninguna biblioteca, python puro, escapa con seguridad el texto en texto html:

text.replace(''<'', ''&lt;'').replace(''>'', ''&gt;'').replace(''&'', ''&amp;'' ).encode(''ascii'', ''xmlcharrefreplace'')


No es la manera más fácil, pero sigue siendo sencilla. La principal diferencia con el módulo cgi.escape : aún funcionará correctamente si ya tiene &amp; en tu texto Como puede ver en los comentarios:

Versión cgi.escape

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

versión regex

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)


También existe el excelente paquete markupsafe .

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

El paquete markupsafe está bien diseñado, y probablemente sea la forma más versátil y pitónica de escaparse, en mi humilde opinión, porque:

  1. el retorno ( Markup ) es una clase derivada de unicode (es decir, isinstance(escape(''str''), unicode) == True
  2. maneja correctamente la entrada de Unicode
  3. funciona en Python (2.6, 2.7, 3.3 y pypy)
  4. respeta los métodos personalizados de objetos (es decir, objetos con una propiedad __html__ ) y las sobrecargas de plantilla ( __html_format__ ).

cgi.escape está bien. Se escapa:

  • < a &lt;
  • > a &gt;
  • & a &amp;

Eso es suficiente para todo el HTML.

EDITAR: si tiene caracteres no ASCII que también desea escapar, para incluirlos en otro documento codificado que use una codificación diferente, como dice Craig , solo use:

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

No te olvides de decodificar data para unicode primero, usando la codificación que codifica.

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 obtener la máxima compatibilidad).

Ejemplo:

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

También vale la pena notar (gracias Greg) es el parámetro de quote extra que toma cgi.escape . Al establecerlo en True , cgi.escape también escapa de los caracteres de comillas dobles ( " ) para que pueda usar el valor resultante en un atributo XML / HTML.

EDITAR: Tenga en cuenta que cgi.escape ha quedado en desuso en Python 3.2 a favor de html.escape , que hace lo mismo, excepto que la quote defecto es True.


cgi.escape debería ser bueno para escapar de HTML en el sentido limitado de escapar de las etiquetas HTML y las entidades de caracteres.

Pero es posible que también deba considerar los problemas de codificación: si el HTML que desea citar tiene caracteres que no son ASCII en una codificación en 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.


Si desea escapar de HTML en una URL:

Probablemente NO es lo que OP deseaba (la pregunta no indica claramente 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.

Lo siguiente es un ejemplo:

#!/usr/bin/python from urllib import quote x = ''+<>^&'' print quote(x) # prints ''%2B%3C%3E%5E%26''

urllib