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

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()
  • 我对这个脚本现在的工作方式有一个大概的了解,并制定了以下工作流程。请让我知道我的流程图(?)有多准确。
     as.string()
     |
     +------------MIMEMultipart
                  |                                                |---content-type
                  |                                   +---header---+---content disposition
                  +----.attach()-----+----MIMEBase----|
                                     |                +---payload (to be encoded in Base64)
                                     +----MIMEText
    
  • 我如何知道何时使用MIMEMultipart,MIMEText和MIMEBase?这似乎是一个复杂的问题,所以也许只是向我提供一些一般的经验法则?
  • 我读到MIME具有树状结构[2],这是否意味着MIMEMultipart始终位于顶部?
  • 在第一个代码块中,MIMEMultipart编码['From'],['To']和['Subject'],但是在Python文档中,MIMEText也可以用于编码['From'],['To ']和['Subject']。我该如何决定使用?
  • 什么是“有效负载”?是否有一些要运输的内容?如果是这样,这包括什么内容(我注意到正文和附件被视为有效内容)?我以为这是一个简单的问题,但我只是找不到满意,可靠和简单的答案。
  • 是真的吗,尽管MIME可以附加的文件格式比某些文本要简单得多,但最后所有编码, header 信息和有效负载都被转换为字符串,以便可以将其传递给.sendmail()?

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

    最佳答案

    电子邮件讯息

    电子邮件由标题(例如“From”,“To”,“Subject”等)和正文(请参阅RFC 822, section 3.1)组成。

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

    您可以使用MIME进行的一项非常有用的操作是指定Content-Type(例如text/htmlapplication/octet-stream)。

    另一个有用的事情是,您可以创建包含多个部分的消息(例如,如果要在HTML中同时包含HTML和图像)。这是通过指定multipart内容类型(RFC 2046, section 5.1)完成的。

    多部分消息

    如果一条消息具有multipart Content-Type,则意味着它由多条消息组成,并且每条消息都定义了自己的Content-Type(可以再次为多部分或其他内容)。多部分消息是由 MIMEMultipart 类表示的Python。

    因此,要回答问题3 :使用MIMEMultipart时,是的,它是树状结构,但是如果仅使用 MIMEText ,则它不是树。

    问题4 询问在哪个类上设置 header (“To”,“From”等)-完成 Message 类,但是所有MIME类都继承自Message,因此可以对它们中的任何一个进行设置,但是这些 header 仅在多部分消息的根部有意义。

    换句话说,如果邮件仅由一个MIME部分组成,请在该部分上指定 header 。如果它由多个部分组成,则根为MIMEMultipart-在该部分上指定 header 。

    问题2 询问“何时使用MIMEMultipart,MIMEText和MIMEBase”。
    -MIMEBase只是一个基类。正如specification所说:“通常,您不会专门创建MIMEBase的实例”
    -MIMEText用于文本(例如text/plaintext/html),如果整个消息是文本格式,或者部分消息是文本格式。
    -MIMEMultipart用于说“我有一个以上的部分”,然后列出这些部分-如果您有附件,也可以这样做,以提供相同内容的替代版本(例如纯文本版本和HTML版本) )

    问题5 :“有效载荷到底是什么?” -这只是消息(或消息部分)内容的花哨词

    问题6 在SMTP中仅使用7位是有限制的。有关更多详细信息,请参见this answer

    我没有完全理解问题1 ,但似乎该图表或多或少是正确的。顺便说一句,我不会在这里使用MIMEBase,因为有 MIMEApplication 似乎更适合于预期的目的。

    10-07 20:30