Python 2.7 实现带附件及图片的邮件发送功能
本文介绍如何使用 Python 2.7 的 email 和 smtplib 模块发送包含文本、图片及附件的邮件。重点解析 MIMEMultipart 类的用法,通过 Message 类封装发件人、收件人、抄送人及附件参数,演示如何构建邮件对象并连接服务器完成发送。
若要编写一个能够发送包含纯文本、图片以及附件的 Python 程序,首先需要掌握两个核心模块:
email 模块用于构建邮件结构,smtplib 模块用于处理 SMTP 协议通信。
此外,需要对 MIME(多用途互联网邮件扩展)机制有基本了解,因为只有通过 MIME 扩展,邮件才能支持图片等媒体文件或非文本信息的传输。
另一个关键细节是使用 MIMEMultipart 类,必须理解其具体用法以及不同参数在功能实现上的区别。
发送邮件的基本流程包含三个步骤:
1. 创建邮件协议对象; 2. 连接邮件服务器; 3. 登录账户并发送邮件。
from email.header import Header
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
import mimetypes
from email.mime.multipart import MIMEMultipart
import os
import smtplib
from email import Encoders as email_encoders
class Message(object):
def __init__(self, from_addr, to_addr, subject="", html="", text=None, cc_addr=[], attachment=[]):
self.from_addr = from_addr
self.subject = subject
if to_addr:
if isinstance(to_addr, list):
self.to_addr = to_addr
else:
self.to_addr = [d for d in to_addr.split(',')]
else:
self.to_addr = []
if cc_addr:
if isinstance(cc_addr, list):
self.cc_addr = cc_addr
else:
self.cc_addr = [d for d in cc_addr.split(',')]
else:
self.cc_addr = []
if html is not None:
self.body = html
self.body_type = "html"
else:
self.body = text
self.body_type = "plain"
self.parts = []
if isinstance(attachment, list):
for file in attachment:
self.add_attachment(file)
def add_attachment(self, file_path, mimetype=None):
"""
If *mimetype* is not specified an attempt to guess it is made. If nothing
is guessed then `application/octet-stream` is used.
"""
if not mimetype:
mimetype, _ = mimetypes.guess_type(file_path)
if mimetype is None:
mimetype = 'application/octet-stream'
type_maj, type_min = mimetype.split('/')
with open(file_path, 'rb') as fh:
part_data = fh.read()
part = MIMEBase(type_maj, type_min)
part.set_payload(part_data)
email_encoders.encode_base64(part)
part_filename = os.path.basename(file_path)
part.add_header('Content-Disposition', 'attachment; filename="%s"'
% part_filename)
part.add_header('Content-ID', part_filename)
self.parts.append(part)
def __to_mime_message(self):
"""Returns the message as
:py:class:`email.mime.multipart.MIMEMultipart`."""
## To get the message work in iOS, you need use multipart/related, not the multipart/alternative
msg = MIMEMultipart('related')
msg['Subject'] = self.subject
msg['From'] = self.from_addr
msg['To'] = ','.join(self.to_addr)
if len(self.cc_addr) > 0:
msg['CC'] = ','.join(self.cc_addr)
body = MIMEText(self.body, self.body_type)
msg.attach(body)
# Add Attachment
for part in self.parts:
msg.attach(part)
return msg
def send(self, smtp_server='localhost'):
smtp = smtplib.SMTP()
smtp.connect(smtp_server)
smtp.sendmail(from_addr=self.from_addr, to_addrs=self.to_addr + self.cc_addr, msg=self.__to_mime_message().as_string())
smtp.close()
在实际编写发送程序时,需严格注意各参数的数据类型:from_addr 应为字符串类型,而 to_addr(收件人)、cc_addr(抄送人)以及 attachment(附件列表)均应为列表类型。
from mail_base import Message
import datetime
from_addr = 'xxx'
mail_to = 'xxx'
def send_go():
time_now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
attach_files = ['testcsv.xlsm','test1.jpg','test2.jpg','test3.jpg']
mail_msg = """
<p>Hi Lockey:</p>
<p><img src="cid:test1.jpg"></p>####要特别注意这里,正文插入图片的特殊格式!!!
<hr/>
<p style="text-indent:16px">Here is the latest paper link from The Economist, you can click <a href="https://lockeycheng.github.io/iooi/index.html" rel="external nofollow" >Go</a> for a full view!</p>
<hr/>
<p>Best Regards</p>
<p>
Any question please mail to <a href='mailto:iooiooi23@163.com'>Lockey23</a>.
</p>
<p>Sent at {} PST</p>
""".format(time_now)
subject = '[Halo] - ' + 'A new paper published!'
msg = Message(from_addr=from_addr,
to_addr=[mail_to],
cc_addr=[mail_to],
subject=subject,
attachment=attach_files,
html=mail_msg
)
msg.send()
if __name__ == '__main__':
send_go()
我们将测试程序命名为 sendGo.py,运行该测试程序以验证功能。
~$ python sendGo.py

以上即为本文的全部内容,希望对读者的学习有所帮助,也欢迎大家继续支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













