我尝试从文件中读取电子邮件,如下所示:
import email
with open("xxx.eml") as f:
msg = email.message_from_file(f)
我收到此错误:
Traceback (most recent call last):
File "I:\fakt\real\maildecode.py", line 53, in <module>
main()
File "I:\fakt\real\maildecode.py", line 50, in main
decode_file(infile, outfile)
File "I:\fakt\real\maildecode.py", line 30, in decode_file
msg = email.message_from_file(f) #, policy=mypol
File "C:\Python33\lib\email\__init__.py", line 56, in message_from_file
return Parser(*args, **kws).parse(fp)
File "C:\Python33\lib\email\parser.py", line 55, in parse
data = fp.read(8192)
File "C:\Python33\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 1920: character maps to <undefined>
该文件包含多部分电子邮件,其中部件以UTF-8编码。文件的内容或编码可能会被破坏,但无论如何我都必须处理它。
如果文件有Unicode错误,我该怎么读?我找不到策略对象compat32
,似乎无法处理异常,让Python继续发生异常。
我该怎么办?
答案 0 :(得分:2)
我无法测试你的消息,所以我不知道这是否真的有效,但你可以自己做字符串解码:
with open("xxx.eml", encoding='utf-8', errors='replace') as f:
text = f.read()
msg = email.message_from_string(f)
如果消息实际上不是UTF-8,那将会为你提供大量的替换字符。但是如果它中有\x81
,那么UTF-8就是我的猜测。
答案 1 :(得分:2)
要在Python 3中解析没有unicode错误的电子邮件,请以二进制模式读取文件并使用email.message_from_binary_file(f)
(或email.message_from_bytes(f.read())
)方法解析内容(请参阅documentation of the email.parser module )。
以下是以与Python 2和3兼容的方式解析消息的代码:
import email
with open("xxx.eml", "rb") as f:
try:
msg = email.message_from_binary_file(f) # Python 3
except AttributeError:
msg = email.message_from_file(f) # Python 2
(使用Python 2.7.13和Python 3.6.0测试)
答案 2 :(得分:0)
with open('email.txt','rb') as f:
ascii_txt = f.read().encode('ascii','backslashreplace')
with open('email.txt','w') as f:
f.write(ascii_text)
#now do your processing stuff
我怀疑这是处理这个问题的最佳方法......但至少它是一种方式...
答案 3 :(得分:0)
一种适用于python 3的方法,它可以找到编码并重新加载正确的编码。
msg=email.message_from_file(open('file.eml', errors='replace'))
codes=[x for x in msg.get_charsets() if x!=None]
if len(codes)>=1 :
msg=email.message_from_file(open('file.eml', encoding=codes[0]))
我尝试使用msg.get_charset()
,但有时会回复None
,而另一种编码可用,因此稍微涉及编码检测