Python使用smtplib实现带附件邮件发送的完整示例
本文提供了基于Python smtplib库发送包含文本、图片及多种附件邮件的完整代码示例。通过解析emailConfig.ini配置文件,实现了SMTP连接、登录及多收件人发送功能。文中对比了旧版与最新版代码,重点解决了附件格式处理问题,并提供了可直接运行的测试脚本,适用于需要自动化邮件通知的开发场景。
本文分享了使用Python标准库smtplib发送邮件的具体实现代码,供读者参考学习。
为解决早期版本中存在的兼容性问题,此处提供经过优化的最新版本代码。
#!/usr/bin/env python
# coding:gbk
"""
FuncName: sendemail.py
Desc: sendemail with text,image,audio,application...
Date: 2016-06-20 10:30
Home: http://blog.csdn.net/z_johnny
Author: johnny
"""
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.utils import COMMASPACE
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.audio import MIMEAudio
import ConfigParser
import smtplib
import os
class MyEmail:
def __init__(self, email_config_path, email_attachment_path):
"""
init config
"""
config = ConfigParser.ConfigParser()
config.read(email_config_path)
self.attachment_path = email_attachment_path
self.smtp = smtplib.SMTP()
self.login_username = config.get('SMTP', 'login_username')
self.login_password = config.get('SMTP', 'login_password')
self.sender = config.get('SMTP', 'login_username') # same as login_username
self.receiver = config.get('SMTP', 'receiver')
self.host = config.get('SMTP', 'host')
#self.port = config.get('SMTP', 'port') 发现加入端口后有时候发邮件出现延迟,故暂时取消
def connect(self):
"""
connect server
"""
#self.smtp.connect(self.host, self.port)
self.smtp.connect(self.host)
def login(self):
"""
login email
"""
try:
self.smtp.login(self.login_username, self.login_password)
except:
raise AttributeError('Can not login smtp!!!')
def send(self, email_title, email_content):
"""
send email
"""
msg = MIMEMultipart() # create MIMEMultipart
msg['From'] = self.sender # sender
receiver = self.receiver.split(",") # split receiver to send more user
msg['To'] = COMMASPACE.join(receiver)
msg['Subject'] = email_title # email Subject
content = MIMEText(email_content, _charset='gbk') # add email content ,coding is gbk, becasue chinese exist
msg.attach(content)
for attachment_name in os.listdir(self.attachment_path):
attachment_file = os.path.join(self.attachment_path,attachment_name)
with open(attachment_file, 'rb') as attachment:
if 'application' == 'text':
attachment = MIMEText(attachment.read(), _subtype='octet-stream', _charset='GB2312')
elif 'application' == 'image':
attachment = MIMEImage(attachment.read(), _subtype='octet-stream')
elif 'application' == 'audio':
attachment = MIMEAudio(attachment.read(), _subtype='octet-stream')
else:
attachment = MIMEApplication(attachment.read(), _subtype='octet-stream')
attachment.add_header('Content-Disposition', 'attachment', filename = ('gbk', '', attachment_name))
# make sure "attachment_name is chinese" right
msg.attach(attachment)
self.smtp.sendmail(self.sender, receiver, msg.as_string()) # format msg.as_string()
def quit(self):
self.smtp.quit()
def send():
import time
ISOTIMEFORMAT='_%Y-%m-%d_%A'
current_time =str(time.strftime(ISOTIMEFORMAT))
email_config_path = './config/emailConfig.ini' # config path
email_attachment_path = './result' # attachment path
email_tiltle = 'johnny test'+'%s'%current_time # as johnny test_2016-06-20_Monday ,it can choose only file when add time
email_content = 'python发送邮件测试,包含附件'
myemail = MyEmail(email_config_path,email_attachment_path)
myemail.connect()
myemail.login()
myemail.send(email_tiltle, email_content)
myemail.quit()
if __name__ == "__main__":
# from sendemail import SendEmail
send()
项目依赖一个名为emailConfig.ini的配置文件,用于存储SMTP服务器参数。
在代码中指定配置文件路径时,需确保路径与程序实际运行目录保持一致。
;login_username : 登陆发件人用户名 ;login_password : 登陆发件人密码 ;host:port : 发件人邮箱对应的host和端口,如:smtp.163.com:25 和 smtp.qq.com:465 ;receiver : 收件人,支持多方发送,格式(注意英文逗号): 123456789@163.com,zxcvbnm@qq.com [SMTP] login_username = johnny@163.com login_password = johnny host = smtp.163.com port = 25 receiver = johnny1@qq.com,johnny2@163.com,johnny3@gmail.com
早期版本代码中存在的一些已知问题如下所述。
#!/usr/bin/env python
#coding: utf-8
'''''
FuncName: smtplib_email.py
Desc: 使用smtplib发送邮件
Date: 2016-04-11 14:00
Author: johnny
'''
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email.utils import COMMASPACE,formatdate
from email import encoders
def send_email_text(sender,receiver,host,subject,text,filename):
assert type(receiver) == list
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = COMMASPACE.join(receiver)
msg['Subject'] = subject
msg['Date'] = formatdate(localtime=True)
msg.attach(MIMEText(text)) #邮件正文内容
for file in filename: #邮件附件
att = MIMEBase('application', 'octet-stream')
att.set_payload(open(file, 'rb').read())
encoders.encode_base64(att)
if file.endswith('.html'): # 若不加限定,jpg、html等格式附件是bin格式的
att.add_header('Content-Disposition', 'attachment; filename="今日测试结果.html"') # 强制命名,名称未成功格式化,如果可以解决请联系我
elif file.endswith('.jpg') or file.endswith('.png') :
att.add_header('Content-Disposition', 'attachment; filename="pic.jpg"')
else:
att.add_header('Content-Disposition', 'attachment; filename="%s"' % file)
msg.attach(att)
smtp = smtplib.SMTP(host)
smtp.ehlo()
smtp.starttls()
smtp.ehlo()
smtp.login(username,password)
smtp.sendmail(sender,receiver, msg.as_string())
smtp.close()
if __name__=="__main__":
sender = 'qqq@163.com'
receiver = ['www@qq.com']
subject = "测试"
text = "johnny'lab test"
filename = [u'测试报告.html','123.txt',u'获取的信息.jpg']
host = 'smtp.163.com'
username = 'qqq@163.com'
password = 'qqq'
send_email_text(sender,receiver,host,subject,text,filename)
经测试验证,使用Header模块并未导致标题显示异常,因此新版代码中未采用该方式。
若发现附件中的HTML、JPG或PNG文件在接收端显示为二进制“bin”格式,请联系作者;该问题已在上述最新版代码中得到解决,希望本文能对大家有所帮助。
点击查看:Python 邮件smtplib发送示例
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













