2009-03-31 20 views
47

posibles duplicados:entidades convertir HTML a Unicode y viceversa

¿cómo convertir las entidades HTML a Unicode y viceversa en Python ?

+16

@Jarret Hardie: en realidad, mostrar y Tell está perfectamente bien en el SO. Desde la primera entrada en las preguntas más frecuentes (http://stackoverflow.com/faq) "También está perfectamente bien hacer y responder su propia pregunta de programación". Aunque, también se recomienda buscar duplicados también. – chauncey

+12

Estoy publicando preguntas que he respondido por mí mismo en el pasado para el beneficio de otros usuarios que buscan respuestas similares. – hekevintran

+6

+1 Él está contribuyendo al conjunto de datos. –

Respuesta

22

Necesita tener BeautifulSoup.

from BeautifulSoup import BeautifulStoneSoup 
import cgi 

def HTMLEntitiesToUnicode(text): 
    """Converts HTML entities to unicode. For example '&' becomes '&'.""" 
    text = unicode(BeautifulStoneSoup(text, convertEntities=BeautifulStoneSoup.ALL_ENTITIES)) 
    return text 

def unicodeToHTMLEntities(text): 
    """Converts unicode to HTML entities. For example '&' becomes '&'.""" 
    text = cgi.escape(text).encode('ascii', 'xmlcharrefreplace') 
    return text 

text = "&, ®, <, >, ¢, £, ¥, €, §, ©" 

uni = HTMLEntitiesToUnicode(text) 
htmlent = unicodeToHTMLEntities(uni) 

print uni 
print htmlent 
# &, ®, <, >, ¢, £, ¥, €, §, © 
# &amp;, &#174;, &lt;, &gt;, &#162;, &#163;, &#165;, &#8364;, &#167;, &#169; 
+1

La aplicación BeautifulSoup ha cambiado. Consulte el [documento] más reciente (http://www.crummy.com/software/BeautifulSoup/bs4/doc/). – bahmait

+0

@hekevintran: ¿Es posible imprimir '& # x00A2 ;, & # x00A3 ;, & # x00A5 ;, & # x20AC ;, & # x00A7 ;, & # x00A9;' en lugar de '¢, £, ¥, €, §, ©'. ¿Alguna idea? – Jagath

78

En cuanto a la "inversa" (que necesitaba a mí mismo, que me lleva a encontrar a esta pregunta, lo cual no ayuda, y posteriormente another site which had the answer):

u'some string'.encode('ascii', 'xmlcharrefreplace') 

devolverá una cadena sin formato con cualquier carácter no ascii convertido en entidades XML (HTML).

+1

Me he olvidado de xmlcharrefreplace y esto fue muy útil. Cada vez que necesito almacenar de forma segura caracteres codificados o no ASCII en mysql, encuentro que necesito usar este método. – cybertoast

+1

Esto no funciona con una cadena literal que contiene el carácter Unicode U + 2019 entidad HTML equivalente ’ ¿No es esto lo que la pregunta estaba pidiendo (esta respuesta convierte ascii que es un subconjunto de Unicode)? text.decode ('utf-8'). Encode ('ascii', 'xmlcharrefreplace') –

+1

@MikeS Funciona sin problemas; '>>> u '\ u2019'.encode (' utf-8 '). decode (' utf-8 '). encode (' ascii ',' xmlcharrefreplace ')' da' '’' ' –

4

Como hekevintran respuesta sugiere, puede utilizar cgi.escape(s) para la codificación de las picaduras, pero observa que la codificación de la cita es falsa por defecto en esa función y que puede ser una buena idea para pasar el argumento quote=True palabra clave junto con su cadena. Pero incluso pasando quote=True, la función no se escapará comillas simples ("'") (Debido a estos problemas la función ha sido deprecated desde la versión 3.2)

Se ha sugerido utilizar en lugar de html.escape(s)cgi.escape(s). (Nuevo en la versión 3.2)

También html.unescape(s) ha sido introduced in version 3.4.

Así que en Python 3.4 se puede:

  • html.escape(text).encode('ascii', 'xmlcharrefreplace').decode() uso para convertir caracteres especiales a entidades HTML.
  • Y html.unescape(text) para convertir entidades HTML de nuevo a representaciones de texto sin formato.
+1

En Python 2.7 usted puede usar HTMLParser.unescape (texto) – frank

12

actualización para Python 2.7 y BeautifulSoup4

Unescape - Unicode HTML a Unicode con htmlparser (2 Python.7 lib estándar):

>>> escaped = u'Monsieur le Cur&eacute; of the &laquo;Notre-Dame-de-Gr&acirc;ce&raquo; neighborhood' 
>>> from HTMLParser import HTMLParser 
>>> htmlparser = HTMLParser() 
>>> unescaped = htmlparser.unescape(escaped) 
>>> unescaped 
u'Monsieur le Cur\xe9 of the \xabNotre-Dame-de-Gr\xe2ce\xbb neighborhood' 
>>> print unescaped 
Monsieur le Curé of the «Notre-Dame-de-Grâce» neighborhood 

Unescape - Unicode HTML a Unicode con bs4 (BeautifulSoup4):

>>> html = '''<p>Monsieur le Cur&eacute; of the &laquo;Notre-Dame-de-Gr&acirc;ce&raquo; neighborhood</p>''' 
>>> from bs4 import BeautifulSoup 
>>> soup = BeautifulSoup(html) 
>>> soup.text 
u'Monsieur le Cur\xe9 of the \xabNotre-Dame-de-Gr\xe2ce\xbb neighborhood' 
>>> print soup.text 
Monsieur le Curé of the «Notre-Dame-de-Grâce» neighborhood 

Escape - Unicode a Unicode HTML con bs4 (BeautifulSoup4):

>>> unescaped = u'Monsieur le Curé of the «Notre-Dame-de-Grâce» neighborhood' 
>>> from bs4.dammit import EntitySubstitution 
>>> escaper = EntitySubstitution() 
>>> escaped = escaper.substitute_html(unescaped) 
>>> escaped 
u'Monsieur le Cur&eacute; of the &laquo;Notre-Dame-de-Gr&acirc;ce&raquo; neighborhood' 
+0

upvote para mostrar una solución de biblioteca estándar sin dependencias –

+0

Revisitando Acabo de ver el comentario @bobince dejado en la pregunta que apunta a [esta respuesta] (http://stackoverflow.com/a/663128/1599229). Como 'htmlparser' está documentado ahora, y como ese comentario no es prominente, deja esa parte de la respuesta. – bahmait

0

Utilicé la siguiente función para convertir unicode ripeado de un archivo xls en un archivo html conservando los caracteres especiales que se encuentran en el archivo xls:

def html_wr(f, dat): 
    ''' write dat to file f as html 
     . file is assumed to be opened in binary format 
     . if dat is nul it is replaced with non breakable space 
     . non-ascii characters are translated to xml  
    ''' 
    if not dat: 
     dat = '&nbsp;' 
    try: 
     f.write(dat.encode('ascii')) 
    except: 
     f.write(html.escape(dat).encode('ascii', 'xmlcharrefreplace')) 

esperanza esto es útil a alguien

0

Si alguien como yo es que se pregunta por qué algunos números de entidad (códigos) como &#153; (for trademark symbol), &#128; (for euro symbol) no están codificados adecuadamente, la razón está en la norma ISO-8859-1 (también conocido como Windows-1252) esos caracteres no están definidos.

También tenga en cuenta que, el juego de caracteres predeterminado a partir del HTML5 es UTF-8 era la norma ISO-8859-1 para html4

Por lo tanto, vamos a tener que solucionar de alguna manera (Encontrar & reemplazar a los que en un principio)

de referencia (punto de partida) de la documentación de Mozilla

https://developer.mozilla.org/en-US/docs/Web/Guide/Localizations_and_character_encodings

Cuestiones relacionadas