web-dev-qa-db-fra.com

Convertir des entités HTML en Unicode et vice versa

Doublons possibles:

Comment convertir des entités HTML en Unicode et vice versa en Python?

62
hekevintran

Vous devez avoir 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;
29
hekevintran

Quant au "vice versa" (dont j'avais besoin moi-même, me conduisant à trouver cette question, ce qui n'a pas aidé, et par la suite n autre site qui avait la réponse ):

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

renverra une chaîne simple avec tous les caractères non ascii transformés en entités XML (HTML).

92
Isaac

Mise à jour pour Python 2.7 et BeautifulSoup4

Unescape - Unicode HTML à unicode avec htmlparser (bibliothèque standard Python 2.7):

>>> 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 pour unicode avec 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

Échap - Unicode pour unicode HTML avec 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'
19
scharfmn

Comme l'indique la réponse hekevintran , vous pouvez utiliser cgi.escape(s) pour coder les piqûres, mais notez que le codage des guillemets est faux par défaut dans cette fonction et il peut être judicieux de passer l'argument du mot clé quote=True à côté de votre chaîne. Mais même en passant quote=True, La fonction n'échappera pas aux guillemets simples ("'") (En raison de ces problèmes, la fonction a été déconseillée depuis la version 3.2)

Il a été suggéré d'utiliser html.escape(s) au lieu de cgi.escape(s). (Nouveau dans la version 3.2)

html.unescape(s) a également été introduit dans la version 3.4 .

Donc en python 3.4 vous pouvez:

  • Utilisez html.escape(text).encode('ascii', 'xmlcharrefreplace').decode() pour convertir des caractères spéciaux en entités HTML.
  • Et html.unescape(text) pour reconvertir les entités HTML en représentations en texte brut.
10
AXO

Si quelqu'un comme moi se demande pourquoi certains numéros d'entité (codes) comme &#153; (for trademark symbol), &#128; (for euro symbol) ne sont pas codés correctement, la raison est dans ISO-8859-1 (alias Windows-1252) ces caractères ne sont pas définis.

Notez également que le jeu de caractères par défaut en html5 est utf-8, il était ISO-8859-1 pour html4

Donc, nous devrons contourner en quelque sorte (trouver et remplacer ceux au début)

Référence (point de départ) de la documentation de Mozilla

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

2
brucekaushik

J'ai utilisé la fonction suivante pour convertir unicode extrait d'un fichier xls en un fichier html tout en conservant les caractères spéciaux trouvés dans le fichier 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'))

j'espère que cela est utile à quelqu'un

1
Stephen Ellwood