2009-07-29 5 views
4

Ich muss jede HTML-Entität in seine ASCII-Entsprechung mit Python konvertieren. Mein Anwendungsfall ist, dass ich etwas HTML bereinige, das zum Erstellen von E-Mails verwendet wird, um Klartext-E-Mails aus dem HTML zu erstellen.Konvertieren von HTML-Entitäten zu ASCII in Python

Im Moment kann ich wirklich nur Unicode von diesen Entitäten erstellen, wenn ich ASCII brauche (denke ich), damit die Klartext-E-Mail korrekt mit Dingen wie Akzentbuchstaben liest. Ich denke, ein grundlegendes Beispiel ist die HTML-Entität "& aacute;" oder á wird in ASCII codiert.

Darüber hinaus bin ich nicht einmal 100% sicher, dass ASCII ist, was ich für eine Klartext-E-Mail brauche. Wie Sie sehen können, bin ich bei diesem Coding-Zeug völlig verloren.

Antwort

2

ASCII ist der amerikanische Standard-Code für den Informationsaustausch und enthält nicht einschließlich akzentuierte Buchstaben. Am besten ist es, Unicode zu bekommen (wie du sagst) und es als UTF-8 zu kodieren (vielleicht ISO-8859-1 oder irgendeine seltsame Codepage, wenn du mit schlecht codierten User-Agents/Clients arbeitest, Seufzer) - - Der Content-Type-Header dieses Teils zusammen mit text/plain kann ausdrücken, welche Kodierung Sie verwenden möchten (Ich empfehle UTF-8 auszuprobieren, es sei denn, Sie haben positiv gezeigt, dass es nicht funktioniert - es ist fast universell unterstützt in diesen Tagen und VIEL flexibler als jeder ISO-8859 oder "Codepage" Hack!).

+0

Das hat gut funktioniert, Sachen zuerst zu Unicode und dann zu UTF-8 zu bewegen, zumindest in meinen Vorversuchen. Wir müssen morgen ein paar Mails verschicken und sehen, wie es in den E-Mail-Clients abgespielt wird. Danke für die ausführliche Erklärung, was ich auch wirklich möchte. – aezell

+0

@aezell, gern geschehen! –

1

Sie können das htmlentitydefs Paket:

import htmlentitydefs 
print htmlentitydefs.entitydefs['aacute'] 

Grundsätzlich entitydefs ist nur ein Wörterbuch, und Sie können sehen, indem sie bei der Python-Prompts:

from pprint import pprint 
pprint htmlentitydefs.entitydefs 
+1

das gibt dir (grob) ISO-8859-1-Codes - das ist heutzutage ein hoffnungslos veralteter Ansatz auch für einen hartnäckigen "Western-/Europa-Rassisten" (zum Beispiel passt sogar das _Euro-Zeichen dort nicht ...! !!). htmlentitydefs.name2codepoint, das Ihnen den numerischen Codepunkt (den Sie in eine Unicode-Zeichenkette der Länge 1 mit unichr - und dann .encode, wie Sie wollen) einheitlich gibt, ist sehr zu bevorzugen. –

+0

Danke für die Eingabe ars. Es scheint mir sicherlich das ASCII-ische Zeug zu geben, nach dem ich gefragt habe, aber ich brauchte auch ein bisschen mehr Anleitung zu meinem Anwendungsfall. – aezell

+0

@aezell: Sicher Sache.Ich bevorzuge auch Alex 'Antwort auf das große Ganze sowie seine spezifischen Vorschläge zu meiner eigenen Antwort. :) – ars

8

Dies ist die komplette Implementierung, die auch Unicode-HTML-Entitäten behandelt. Vielleicht finden Sie es nützlich.

Es gibt eine Unicode-Zeichenfolge zurück, die nicht ascii ist, aber wenn Sie plain ascii möchten, können Sie die Ersetzungsoperationen so ändern, dass die Entitäten durch eine leere Zeichenfolge ersetzt werden.

def convert_html_entities(s): 
    matches = re.findall("&#\d+;", s) 
    if len(matches) > 0: 
     hits = set(matches) 
     for hit in hits: 
      name = hit[2:-1] 
      try: 
       entnum = int(name) 
       s = s.replace(hit, unichr(entnum)) 
      except ValueError: 
       pass 

    matches = re.findall("&#[xX][0-9a-fA-F]+;", s) 
    if len(matches) > 0: 
     hits = set(matches) 
     for hit in hits: 
      hex = hit[3:-1] 
      try: 
       entnum = int(hex, 16) 
       s = s.replace(hit, unichr(entnum)) 
      except ValueError: 
       pass 

    matches = re.findall("&\w+;", s) 
    hits = set(matches) 
    amp = "&" 
    if amp in hits: 
     hits.remove(amp) 
    for hit in hits: 
     name = hit[1:-1] 
     if htmlentitydefs.name2codepoint.has_key(name): 
      s = s.replace(hit, unichr(htmlentitydefs.name2codepoint[name])) 
    s = s.replace(amp, "&") 
    return s 

Edit: hinzugefügt passend für Hexcodes. Ich benutze das schon seit einer Weile und lief in meine erste Situation mit ', die ein einfaches Zitat/Apostroph ist.

+0

Danke! Arbeitete wie ein Charme :-) – BioGeek

+0

Schöne Antwort. Es scheint, dass in einem Standardmodul etwas dazu gehört. – Andrew

Verwandte Themen