MIMEMultipart、MIMEText、MIMEBase 和用于在 Python 中发送带有文件附件的电子邮件的有效负载

2022-01-17 00:00:00 python email smtp smtplib mime

问题描述

在没有太多 MIME 知识的情况下,我尝试学习如何编写 Python 脚本来发送带有文件附件的电子邮件.在交叉引用 Python 文档、Stack Overflow 问题和一般网络搜索之后,我使用以下代码 [1] 解决了问题,并对其进行了测试.

Without much prior knowledge of MIME, I tried to learned how to write a Python script to send an email with a file attachment. After cross-referencing Python documentation, Stack Overflow questions, and general web searching, I settled with the following code [1] and tested it to be working.

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders

fromaddr = "YOUR EMAIL"
toaddr = "EMAIL ADDRESS YOU SEND TO"

msg = MIMEMultipart()

msg['From'] = fromaddr
msg['To'] = toaddr
msg['Subject'] = "SUBJECT OF THE EMAIL"

body = "TEXT YOU WANT TO SEND"

msg.attach(MIMEText(body, 'plain'))

filename = "NAME OF THE FILE WITH ITS EXTENSION"
attachment = open("PATH OF THE FILE", "rb")

part = MIMEBase('application', 'octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', "attachment; filename= %s" % filename)

msg.attach(part)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(fromaddr, "YOUR PASSWORD")
text = msg.as_string()
server.sendmail(fromaddr, toaddr, text)
server.quit()

  1. 我现在大致了解了这个脚本的工作原理,并制定了以下工作流程.请让我知道我的流程图(?)有多准确.

  1. I have a rough idea of how this script works now, and worked out the following workflow. Please let me know how accurate my flowchart(?) is.

 as.string()  
 |
 +------------MIMEMultipart  
              |                                                |---content-type  
              |                                   +---header---+---content disposition  
              +----.attach()-----+----MIMEBase----|  
                                 |                +---payload (to be encoded in Base64)
                                 +----MIMEText

  • 我如何知道何时使用 MIMEMultipart、MIMEText 和 MIMEBase?这似乎是一个复杂的问题,所以也许只是向我提供一些一般的经验法则?

  • How do I know when to use MIMEMultipart, MIMEText and MIMEBase? This seems like a complicated question, so maybe just offer some general rules-of-thumb to me?

    [1]http://naelshiab.com/tutorial-send-email-python/
    [2]http://blog.magiksys.net/generate-and-send-mail-with-python-tutorial


    解决方案

    电子邮件

    一封电子邮件由标题(例如发件人"、收件人"、主题"等)和正文(参见 RFC 822,第 3.1 节).

    默认情况下,邮件正文被视为纯 ASCII 文本.MIME (RFC 2045, RFC 2046, RFC 2047、RFC 2048、RFC 2049) 定义了允许指定不同类型的电子邮件内容的扩展.

    The body of the message is, by default, treated as plain ASCII text. MIME (RFC 2045, RFC 2046, RFC 2047, RFC 2048, RFC 2049) defines extensions which allow specifying different types of email content.

    使用 MIME 可以做的一件非常有用的事情是指定 Content-Type(例如 text/htmlapplication/octet-stream).

    One very useful thing you are able to with MIME is specify a Content-Type (e.g. text/html or application/octet-stream).

    另一个有用的事情是您可以创建包含多个部分的消息(例如,如果您希望在 HTML 中同时包含 HTML 和图像).这是通过指定 multipart Content-Type (RFC 2046,第 5.1 节).

    Another useful thing is that you can create a message with multiple parts (for instance, if you want to have both HTML and an image within the HTML). This is done by specifying a multipart Content-Type (RFC 2046, section 5.1).

    如果一条消息有一个 multipart Content-Type,这意味着它由多个消息组成,并且每个消息都定义了自己的 Content-Type(也可以是 multipart 或其他内容).多部分消息在 Python 中由 表示MIMEMultipart 类.

    If a message has a multipart Content-Type, that means it consists of multiple messages and each of them defines its own Content-Type (which can again be multipart or something else). Multipart messages are in Python represented by MIMEMultipart class.

    所以,回答问题3:当使用MIMEMultipart时,是的,它是一个树状结构,但如果只有MIMEText不是一棵树.

    So, to answer question 3: When MIMEMultipart is used, then yes, it is a tree-like structure, but if only MIMEText is used, then it is not a tree.

    问题 4 询问在哪个类上设置标头(To"、From"等) - Message 类,但所有 MIME 类继承自 Message,因此可以在其中任何一个上完成,但这些标头仅对多部分消息的根部分有意义.

    Question 4 asks on which class to set the headers ("To", "From" etc.) - that is done the the Message class, but all MIME classes inherit from Message, so it can be done on any of them, but those headers only make sense on the root part of a multipart message.

    换句话说,如果一封邮件仅包含一个 MIME 部分,请在该部分上指定标头.如果它由多个部分组成,则根是 MIMEMultipart - 在该部分上指定标头.

    In other words, if a message consists of only one MIME part, specify headers on that part. If it consists of mutiple parts, then the root is a MIMEMultipart - specify the headers on that part.

    问题 2 询问 何时使用 MIMEMultipart、MIMEText 和 MIMEBase".

    • MIMEBase 只是一个基类.正如 规范所说:通常你不会创建专门的 MIMEBase 实例"
    • MIMEText 用于文本(例如 text/plaintext/html),如果整个消息是文本格式,或者如果一部分是.
    • MIMEMultipart 用于说我有不止一个部分",然后列出这些部分——如果你有附件,你也这样做提供相同内容的替代版本(例如纯文本版本加 HTML 版本)
    • MIMEBase is just a base class. As the specification says: "Ordinarily you won’t create instances specifically of MIMEBase"
    • MIMEText is for text (e.g. text/plain or text/html), if the whole message is in text format, or if a part of it is.
    • MIMEMultipart is for saying "I have more than one part", and then listing the parts - you do that if you have attachments, you also do it to provide alternative versions of the same content (e.g. a plain text version plus an HTML version)

    问题 5 究竟什么是有效负载"?" - 这只是消息内容(或消息部分)的一个花哨的词

    Question 5 "What exactly is a "payload"?" - that is just a fancy word for the content of the message (or message part)

    问题 6 在 SMTP 中只能使用 7 位是有限制的.有关详细信息,请参阅此答案.

    Question 6 There is a limitation to using only 7 bits in SMTP. See this answer for more details.

    问题1我没完全看懂,不过好像图表差不多是对的.顺便说一句,我不会在这里使用 MIMEBase,因为有 MIMEApplication 似乎更适合预期目的.

    I did not completely understand Question 1, but it seems that the chart is more or less correct. BTW, I would not use MIMEBase here, because there is MIMEApplication which seems more appropriate for the intended purpose.

  • 相关文章