Konvertieren Sie HTML-Entitäten in Unicode und umgekehrt

70

Mögliche Duplikate:

Wie konvertiert man HTML-Entitäten in Python in Unicode und umgekehrt?

Hekevintran
quelle
16
@Jarret Hardie: Eigentlich ist Show-and-Tell auf SO vollkommen in Ordnung. Ab dem ersten Eintrag in den FAQ ( stackoverflow.com/faq ) "Es ist auch vollkommen in Ordnung, Ihre eigene Programmierfrage zu stellen und zu beantworten". Es wird jedoch auch empfohlen, auch nach Duplikaten zu suchen.
Chauncey
13
Ich poste Fragen, die ich in der Vergangenheit für mich selbst beantwortet habe, zum Nutzen anderer Benutzer, die nach ähnlichen Antworten suchen.
Hekevintran
Kann auch ohne externe Bibliotheken durchgeführt werden. Siehe stackoverflow.com/questions/663058/html-entity-codes-to-text/…
bobince
6
+1 Er trägt zum Datensatz bei.
Ryan Townshend
2
Diese Frage ist umfangreicher als die, auf die der Link "Duplizieren" hinweist: In dieser Frage wird auch nach "Umgekehrt" gefragt, dh von Unicode zu HTML-Entitäten.
Vebjorn Ljosa

Antworten:

95

Was das "Umgekehrte" betrifft (das ich selbst brauchte, was mich dazu brachte, diese Frage zu finden, die nicht half, und anschließend eine andere Seite, die die Antwort hatte ):

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

gibt eine einfache Zeichenfolge mit allen Nicht-ASCII-Zeichen zurück, die in XML-Entitäten (HTML) umgewandelt wurden.

Isaac
quelle
1
Ich habe xmlcharrefreplace vergessen und das war sehr hilfreich. Jedes Mal, wenn ich verschlüsselte oder nicht-ASCII-Zeichen sicher in MySQL speichern muss, muss ich diese Methode verwenden.
Cybertoast
1
Dies funktioniert nicht mit einem Zeichenfolgenliteral, das das HTML-Entitätsäquivalent & # 8217; des Unicode-Zeichens U + 2019 enthält. Ist es nicht das, wonach die Frage gefragt hat (diese Antwort konvertiert ASCII, eine Teilmenge von Unicode)? text.decode ('utf-8'). encode ('ascii', 'xmlcharrefreplace')
Mike S
1
@ MikeS Es funktioniert ohne Probleme; >>> u'\u2019'.encode('utf-8').decode('utf-8').encode('ascii', 'xmlcharrefreplace')gibt'’'
Piotr Dobrogost
31

Sie müssen BeautifulSoup haben .

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;
Hekevintran
quelle
2
Die BeautifulSoup-API hat sich geändert. Bitte lesen Sie das neueste Dokument .
scharfmn
@hekevintran: Ist es möglich, "& # x00A2;, & # x00A3;, & # x00A5;, & # x20AC;, & # x00A7;, & # x00A9;" zu drucken. anstelle von '¢, £, ¥, €, §, ©'. Irgendeine Idee?
Jagath
5
Diese Antwort benötigt dringend ein Python3-Update.
Routhinator
21

Update für Python 2.7 und BeautifulSoup4

Unescape - Unicode-HTML zum Unicode mit htmlparser(Python 2.7 Standardbibliothek):

>>> 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 zum Unicode mit 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 zu Unicode HTML mit 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'
scharfmn
quelle
2
Gegenstimme für das Anzeigen einer Standardbibliothekslösung ohne Abhängigkeiten
Hartley Brody
Bei einem erneuten Besuch habe ich gerade den Kommentar @bobince zu der Frage gesehen, die auf diese Antwort verweist . Da htmlparserist jetzt dokumentiert, und da dieser Kommentar nicht prominent ist, bleibt dieser Teil der Antwort.
scharfmn
12

Wie aus der Antwort von hekevintran hervorgeht , können Sie die cgi.escape(s)Codierung von Stings verwenden. Beachten Sie jedoch, dass die Codierung von Anführungszeichen in dieser Funktion standardmäßig falsch ist und es möglicherweise eine gute Idee ist, das quote=TrueSchlüsselwortargument neben Ihrer Zeichenfolge zu übergeben. Aber auch durch Übergeben entgeht quote=Truedie Funktion nicht einfachen Anführungszeichen ( "'") (Aufgrund dieser Probleme ist die Funktion seit Version 3.2 veraltet. )

Es wurde vorgeschlagen, html.escape(s)anstelle von zu verwenden cgi.escape(s). (Neu in Version 3.2)

Wurde html.unescape(s)auch in Version 3.4 eingeführt .

In Python 3.4 können Sie also:

  • Verwenden Sie html.escape(text).encode('ascii', 'xmlcharrefreplace').decode()diese Option , um Sonderzeichen in HTML-Entitäten zu konvertieren.
  • Und html.unescape(text)zum Konvertieren von HTML-Entitäten zurück in Klartextdarstellungen.
AXO
quelle
1
In Python 2.7 können Sie HTMLParser.unescape (Text) verwenden
Frank
4
$ python3 -c "
> import html
> print(
>     html.unescape('&amp;&#169;&#x2014;')
> )"
&©—

$ python3 -c "
> import html
> print(
>     html.escape('&©—')
> )"
&amp;©—

$ python2 -c "
> from HTMLParser import HTMLParser
> print(
>     HTMLParser().unescape('&amp;&#169;&#x2014;')
> )"
&©—

$ python2 -c "
> import cgi
> print(
>     cgi.escape('&©—')
> )"
&amp;©—

HTML erfordert nur strikt, dass &(kaufmännisches Und) und <(linke spitze Klammer / Vorzeichen) maskiert werden. https://html.spec.whatwg.org/multipage/parsing.html#data-state

Jan Kyu Peblik
quelle
2

Wenn sich jemand wie ich da draußen fragt, warum einige Entitätsnummern (Codes) &#153; (for trademark symbol), &#128; (for euro symbol)nicht richtig codiert sind, liegt der Grund darin, dass diese Zeichen in ISO-8859-1 (auch bekannt als Windows-1252) nicht definiert sind.

Beachten Sie auch, dass der Standardzeichensatz ab HTML5 utf-8 ist und ISO-8859-1 für HTML4 war

Also müssen wir irgendwie umgehen (zuerst diese finden und ersetzen)

Referenz (Ausgangspunkt) aus Mozillas Dokumentation

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

brucekaushik
quelle
1

Ich habe die folgende Funktion verwendet, um aus einer XLS-Datei gerippten Unicode in eine HTML-Datei zu konvertieren und dabei die in der XLS-Datei enthaltenen Sonderzeichen beizubehalten:

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'))

hoffe, das ist nützlich für jemanden

Stephen Ellwood
quelle
1

Zur python3Verwendung html.unescape():

import html
s = "&amp;"
decoded = html.unescape(s)
# &
Pedro Lobito
quelle
0
#!/usr/bin/env python3
import fileinput
import html

for line in fileinput.input():
    print(html.unescape(line.rstrip('\n')))
Glückliches Gesicht
quelle