【问题标题】:How to save sent email with attachment如何保存已发送的带有附件的电子邮件
【发布时间】:2022-04-03 20:59:42
【问题描述】:

我写了一个代理来使用 smtp 服务器发送电子邮件。 发送一切正常,但我想保存一个.eml 文件,其中不仅包含正文,还包含所有附件。

我尝试了几种方法都没有运气。

这是我的代码(请不要查看缺少的错误检查)。 为简单起见,还缺少部分代码。

from email.mime.multipart import MIMEBase, MIMEMultipart
from email import encoders, message, utils, generator , message_from_bytes,message_from_string

def _attachment(filename,file_path=None):
    fp_filename = ''
    if file_path is not None:
        fp_filename = file_path+'/'+filename
    else:
        fp_filename = self.attachdir+'/'+filename
    fd = open(fp_filename, 'rb')
    mimetype, mimeencoding = mimetypes.guess_type(filename)
    if mimeencoding or (mimetype is None):
        mimetype = 'application/octet-stream'
    maintype, subtype = mimetype.split('/')
    if maintype == 'text':
        retval = MIMEText(fd.read(), _subtype=subtype)
    else:
        retval = MIMEBase(maintype, subtype)
        retval.set_payload(fd.read())
        encoders.encode_base64(retval)
    retval.add_header('Content-Disposition', 'attachment',
            filename = filename)
    fd.close()
    return retval


# ...
# prepare msg body
msg_content = """
<!DOCTYPE html>
<html>
<head>
<title>My Title</title>
<style type="text/css">
  span.bold {font-weight: bold;}
  table.noborder {border: 0px; padding: 8px;}
  th {text-align: left;}
</style>
 </head>
<body>
<p>
  Hello From Me :-)
</p>
</body>
</html>
"""

#create message obgject
msg = MIMEMultipart('alternative')
msg.attach(MIMEText(msg_content, 'html', 'utf-8'))

msg['From'] = mfrom
msg['To'] = recipient
msg['Reply-to'] = reply
msg['Subject'] = subject
msg['Date'] = utils.formatdate(localtime = 1)

msg.attach(_attachment(filename='samplefile.pdf',file_path='./'))

# no error check reported in this code sample
conn = smtplib.SMTP_SSL(smtpserver,smtpport)
conn.login(smtplogin, smtppass)
conn.sendmail(e.mfrom, [comm.destinatario], msg.as_string())
conn.quit()

with open('file_1.eml', 'w') as f:
    gen = generator.Generator(f)
    gen.flatten(msg)
                        

 msg_b = message_from_string(msg.as_string())
 with open('file_2.eml', 'wb') as f:
     f.write(bytes(msg_b))
 
 with open('file_3.eml', 'wb') as f:
     f.write(msg.as_bytes())

在每个文件 (1,2,3) 中,我只能看到电子邮件正文:没有附件!

你能帮帮我吗?

【问题讨论】:

  • 当我运行您的代码时,我会得到 3 个带有附件的文件。更好地创建产生问题的最小工作代码 - 然后我们可以测试它并查看问题。目前你的代码对我来说没问题。
  • 谢谢@furas。也许这是一个可视化问题。当我用 Outlook 打开 eml 文件时,我看不到附件。但是当我去查看收到的电子邮件时,在 Webmail 上,我可以看到附件。我也尝试在已发送邮件中上传邮件,从webmail查看,没关系,这是一个奇怪的outlook行为。

标签: python email email-attachments


【解决方案1】:

从 OP 对问题的编辑移至答案。

使用email.message.EmailMessage,如Python docs 中所述。

旧方法在某些用户查看附件时产生了一些问题。

这是工作代码:

import mimetypes
import smtplib
from email import utils
from email.message import EmailMessage
from email.policy import SMTP

import html2text

# prepare msg body
msg_content = """
<!DOCTYPE html>
<html>
<head>
<title>My Title</title>
<style type="text/css">
  span.bold {font-weight: bold;}
  table.noborder {border: 0px; padding: 8px;}
  th {text-align: left;}
</style>
 </head>
<body>
<p>
  Hello From Me :-)
</p>
</body>
</html>
"""
mfrom = 'addremail@example.com'
mto = 'recipient@example.com'
file_to_attach = 'testfile.PDF'
subject = 'test attachment'
smtp_server = 'localhost' 

# create message object
msg = EmailMessage()

msg['From'] = mfrom
msg['To'] = mto
# msg['Reply-to'] = reply
msg['Subject'] = subject
msg['Date'] = utils.formatdate(localtime = 1)
# generate text version
ht = html2text.HTML2Text()
ht.ignore_links = False
# Add Text Version
msg.set_content(ht.handle(msg_content))
# Add HTML Version
msg.add_alternative(msg_content, subtype='html')
# Manage Attachment
ctype, encoding = mimetypes.guess_type(file_to_attach)
if ctype is None or encoding is not None:
    # No guess could be made, or the file is encoded (compressed), so
    # use a generic bag-of-bits type.
    ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
with open(file_to_attach, 'rb') as fp:
    # add attachment
    msg.add_attachment(fp.read(),
                       maintype=maintype,
                       subtype=subtype,
                       filename=file_to_attach)


# store the message
with open('mail_out.eml', 'wb') as fp:
    fp.write(msg.as_bytes(policy=SMTP))

# send the message
with smtplib.SMTP(smtp_server) as s:
    # set debug if needed
    s.set_debuglevel(1)
    # send
    s.send_message(msg)

【讨论】:

    猜你喜欢
    • 2016-02-12
    • 2015-09-09
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    相关资源
    最近更新 更多