Python 如何使email.Header.decode_头使用非ASCII字符?
我借用了下面的代码来解析电子邮件标题,另外还添加了一个标题。诚然,我不完全理解为什么要围绕着Python 如何使email.Header.decode_头使用非ASCII字符?,python,unicode,utf-8,character-encoding,non-ascii-characters,Python,Unicode,Utf 8,Character Encoding,Non Ascii Characters,我借用了下面的代码来解析电子邮件标题,另外还添加了一个标题。诚然,我不完全理解为什么要围绕着email.Headers模块的简单用法进行所有的搭建 值得注意的是,标题没有实例化;相反,它的decode\u头函数被调用: class DecodedHeader(object): def __init__(self, s, folder): self.msg=email.message_from_string(s[1]) self.info=parseList
email.Headers
模块的简单用法进行所有的搭建
值得注意的是,标题
没有实例化;相反,它的decode\u头
函数被调用:
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
问题是:当标题(val)包含非ASCII字符(如Ä和ä)时,我得到:
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)
回溯(最近一次呼叫最后一次):
文件“v12.py”,第434行,在
main()
文件“v12.py”,第396行,在main中
writer.writerow(msg)
writerow中的文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py”,第152行
返回self.writer.writerow(self.\u dict\u to\u list(rowdict))
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/csv.py”,第149行,在目录列表中
return[rowdict.get(key,self.restval)用于输入self.fieldnames]
get中第198行的文件“v12.py”
返回self.\uuu getitem\uuuu(键)
文件“v12.py”,第196行,在\uu getitem中__
返回self.\u convert(email.Header.decode\u Header(val),name)
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/email/header.py”,第76行,在decode_头中
header=str(header)
UnicodeEncodeError:“ascii”编解码器无法对位置1中的字符u'\xe4'进行编码:序号不在范围内(128)
其中u'\xe4'是ä
我试过几件事:
- 将#——编码:utf-8——添加到header.py的顶部
- 调用
上的unicode(),然后将其传递给val
decode\u header()
- 调用
上的.encode('utf-8'),然后将其传递到val
decode\u头()
- 调用
上的.encode('ISO-8859-1'),然后将其传递到val
decode\u头()
以上任何一项都没有乐趣。这里的原因是什么?鉴于我希望保持上述
email.Header
的使用(Header未直接实例化),我们如何确保非ASCII字符通过decode\u Header
成功解码?必须正确编码Header才能解码。看起来val
来自已经存在的消息,因此该消息可能是错误的。该错误指示它是Unicode字符串,但此时它应该是字节字符串。的Python帮助中的示例非常简单
下面对两个甚至不使用相同编码的标题进行编码:
>>> 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?='
当您提供的示例难以运行时,尝试提供帮助有点令人不快。你可能想看看。我会跳进去,到处捣乱,去体验这个问题,并试图解决它。但是需要比这更多的MCVE来开始。@GreenAsJade Fair point。然而,为了包含其余的代码以及调用的其他模块,只是为了让它运行,我们需要数百行代码。我本以为Python大师能够仅在代码审查时就指出错误。正如我所说,我尝试了各种方法(见上文),并研究了其他一些关于email.Header和编码/编码的SO帖子,但都没有用。@GreenAsJade以下是完整代码的链接:为了重现这个问题,您需要(或创建)至少有一个标题包含像ä这样的字符的电子邮件。问题是你要求我们做工作,所以你不必这样做。如果你能让助手们自己做尽可能多的工作,你就会得到更好的帮助。通常,你会发现,如果你设定自己编写一个简单的例子,导致问题,你会找到解决办法。如果你不这样做,那么至少对我们来说很容易。将链接发布到整个代码通常是没有用的,因为一大块代码并不清楚如何运行。您需要的是一个传递unicode来解码_头的小示例,与其他无关代码分开。这看起来像是解决此问题的MCVE。它假设您可以将任何您喜欢的内容传递给
decode\u headers()
<代码>导入电子邮件。标题打印电子邮件。标题。解码标题(“a”)打印电子邮件。标题。解码标题(u'\xe4')
>>> 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ñ