Wie bekomme ich email.Header.decode_header, um mit Nicht-ASCII-Zeichen zu arbeiten?

Ich leihe den folgenden Code, um E-Mail-Header zu analysieren und zusätzlich einen Header weiter unten auf der Linie hinzuzufügen. Zugegeben, ich verstehe nicht ganz den Grund für all das Gerüst um was sollte einfacher Gebrauch des email.Headers Modul sein.

Bemerkenswert ist, dass Headers nicht instanziiert wird. Eher seine decode_header Funktion heißt:

 class DecodedHeader(object): def __init__(self, s, folder): self.msg=email.message_from_string(s[1]) self.info=parseList(s[0]) self.folder=folder def __getitem__(self,name): if name.lower()=='folder': return self.folder elif name.lower()=='uid': return self.info[1][3] elif name.lower()=='flags': return ','.join(self.info[1][1]) elif name.lower()=='internal-date': ds= self.info[1][5] if Options.dateFormat: ds= time.strftime(Options.dateFormat,imaplib.Internaldate2tuple('INTERNALDATE "'+ds+'"')) return ds elif name.lower()=='size': return self.info[1][7] val= self.msg.__getitem__(name) if val==None: return None return self._convert(email.Header.decode_header(val),name) def get(self,key,default=None): return self.__getitem__(key) def _convert(self, list, name): l=[] for s, encoding in list: try: if (encoding!=None): s=unicode(s,encoding, 'replace').encode(Options.encoding,'replace') except Exception, e: print >>sys.stderr, "Encoding error", e l.append(s) res= "".join(l) if Options.addr and name.lower() in ('from','to', 'cc', 'return-path','reply-to' ): res=self._modifyAddr(res) if Options.dateFormat and name.lower() in ('date'): res = self._formatDate(res) return res 

Hier ist das Problem: Wenn der Header (val) Nicht-ASCII-Zeichen wie Ä und ä enthält, bekomme ich:

 Traceback (most recent call last): File "v12.py", line 434, in <module> main() File "v12.py", line 396, in main writer.writerow(msg) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 152, in writerow return self.writer.writerow(self._dict_to_list(rowdict)) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py", line 149, in _dict_to_list return [rowdict.get(key, self.restval) for key in self.fieldnames] File "v12.py", line 198, in get return self.__getitem__(key) File "v12.py", line 196, in __getitem__ return self._convert(email.Header.decode_header(val),name) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/email/header.py", line 76, in decode_header header = str(header) UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 1: ordinal not in range(128) 

Wo u '\ xe4' ist ä.

Ich habe ein paar Dinge ausprobiert:

  • Hinzufügen von # – – coding: utf-8 – – an die Spitze von header.py
  • Aufruf von Unicode () auf val vor dem Übergang an decode_header()
  • Aufruf von .encode ('utf-8') auf val vor dem Übergang an decode_header()
  • Aufruf von .encode ('ISO-8859-1') auf val vor dem Passieren an decode_header()

Keine Freude mit einer der oben genannten Was ist denn hier? Angesichts der Tatsache, dass ich schaue, um die Verwendung von email.Header wie oben zu behalten (mit Header nicht direkt instanziiert), wie stellen wir sicher, dass Nicht-ASCII-Zeichen erfolgreich von decode_header decodiert werden?

One Solution collect form web for “Wie bekomme ich email.Header.decode_header, um mit Nicht-ASCII-Zeichen zu arbeiten?”

Der Header muss korrekt codiert werden, um decodiert zu werden. Es sieht aus wie val kommt aus einer bereits vorhandenen Nachricht, also vielleicht ist diese Nachricht schlecht. Der Fehler zeigt an, dass es eine Unicode-Zeichenfolge ist, aber es sollte ein Byte-String an diesem Punkt sein. Die Beispiele in der Python-Hilfe für email.header sind einfach.

Unten kodiert zwei Header, die nicht einmal die gleiche Codierung verwenden:

 >>> import email.header >>> h = email.header.Header(u'To: Märk'.encode('iso-8859-1'),'iso-8859-1') >>> h.append(u'From: Jòhñ'.encode('utf8'),'utf8') >>> h <email.header.Header instance at 0x00559F58> >>> s = h.encode() >>> s '=?iso-8859-1?q?To=3A_M=E4rk?= =?utf-8?b?RnJvbTogSsOyaMOx?=' 

Beachten Sie, dass der korrekt codierte Header ein Byte-String mit den eingebetteten Codierungsnamen ist und keine Nicht-ASCII-Zeichen verwendet.

Das dekodiert sie:

 >>> email.header.decode_header(s) [('To: M\xe4rk', 'iso-8859-1'), ('From: J\xc3\xb2h\xc3\xb1', 'utf-8')] >>> d = email.header.decode_header(s) >>> for s,e in d: ... print s.decode(e) ... To: Märk From: Jòhñ 
Python ist die beste Programmiersprache der Welt.