使用python读取eml文件或者远程imap读取邮件时,邮件里面有内嵌图片,源地址是 img src=3D"cid:_Foxmail.1@bebb7=cba-548d-cdd3-c8df-af59616af7cc" 之类的,可以在读取邮件时将图片保存到缓存目录,然后将邮件内容里面的src源地址替换为刚才保存的路径,折腾半天实现了效果,记录下过程
- import imaplib,email
- import quopri
- from email.mime.text import MIMEText
- from flask import Response
- from flask import make_response
-
- @app.route('/')
- def index():
- conn = imaplib.IMAP4("127.0.0.1",143)
- conn.login("user@domain.ld","password")
- conn.select("INBOX")
- ''' python3 要使用str() 否则提示 TypeError: can't concat bytes to int '''
- stat,data = conn.fetch(str(2),'(RFC822)')
- if stat != "OK" or data is None:
- raise KeyError
- ''' 转为message对象,python2使用email.message_from_string '''
- msg = email.message_from_bytes(data[0][1])
- attlist= {}
- for part in msg.walk():
- if not part.is_multipart():
- file = part.get_filename() #附件名
- ''' filename = email.header.decode_header(filename) ==> [(b'\xe5\x8a\xb3\xe5\x8a\xa8\xe6\xb3\x95.png', 'utf-8')] '''
- if file:
- filename = email.header.decode_header(file)[0][0] #附件名
- charset = email.header.decode_header(file)[0][1] #编码
- if part.get_all("Content-ID"):
- content_id = part.get_all("Content-ID")[0][1:-1]
- else:
- content_id = "" #附件ID,也就是邮件源码里面的cid
- ''' 多个附件时将附件名和ID对应保存到dict里面,后面将正文中的cid替换为本地保存路径 '''
- attlist[content_id] = filename
- ''' 附件文件名为中文或有编码的时候要进行转码 '''
- if str(charset) != "None":
- filename = filename.decode(charset)
- filedata = part.get_payload(decode=True) # 附件内容
- ''' 把附件写到文件里面,附件一定要用wb打开,二进制 '''
- with open("/temp/"+filename,"wb") as fw:
- fw.write(filedata)
- fw.close()
- else:
- content = part.get_payload(decode=True) # 邮件正文
- contentd = content.decode()
-
- for x,y in attlist.items():
- ''' 替换cid '''
- contentd = contentd.replace('cid:'+x,'static/temp/'+y)
- return Response(quopri.decodestring(contentd),content_type="text/html; charset=%s" %charset) ##使用quopri转码,不然不能转码源码中的=OA 等字符,为防止乱码,在response时返回邮件内容中的编码
-