最新消息:

Python SMTP 发送带附件电子邮件

Python admin 1124浏览 0评论

Python中发送邮件可通过stmplib模块来发送,但如果要发送附件等信息需其他模块辅助,如可采用email模块发送电子邮件附件。发送一个未知MIME类型的文件附件其基本思路如下:

1. 构造MIMEMultipart对象做为根容器

2、设置根容器属性 (即设置邮件的头部信息,title,from,to)。

3. 构造MIMEText对象做为邮件显示内容并附加到根容器 (注意有两种形式的邮件正文:普通明文邮件和html形式邮件)

4. 构造MIMEBase对象做为文件附件内容并附加到根容器
a. 读入文件内容并格式化
b. 设置附件头

5. 得到格式化后的完整文本

6. 用smtp发送邮件

具体内容参见<programing python(3rd)> 14章第6节 “email: Parsing and Composing Mails”。发送一个未知MIME类型的文件附件实例代码如下:

import smtplib
import email.MIMEMultipart
import email.MIMEText
import email.MIMEBase
import os.path

From = "sender address"
To = "recipients"
file_name = "file name"

server = smtplib.SMTP("smtp server address")
server.login("username","password") #仅smtp服务器需要验证时

# 构造MIMEMultipart对象做为根容器
main_msg = email.MIMEMultipart.MIMEMultipart()

# 构造MIMEText对象做为邮件显示内容并附加到根容器
text_msg = email.MIMEText.MIMEText("this is a test text to text mime")
main_msg.attach(text_msg)

# 构造MIMEBase对象做为文件附件内容并附加到根容器
contype = 'application/octet-stream'
maintype, subtype = contype.split('/', 1)

## 读入文件内容并格式化
data = open(file_name, 'rb')
file_msg = email.MIMEBase.MIMEBase(maintype, subtype)
file_msg.set_payload(data.read( ))
data.close( )
email.Encoders.encode_base64(file_msg)

## 设置附件头
basename = os.path.basename(file_name)
file_msg.add_header('Content-Disposition',
 'attachment', filename = basename)
main_msg.attach(file_msg)

# 设置根容器属性
main_msg['From'] = From
main_msg['To'] = To
main_msg['Subject'] = "attach test "
main_msg['Date'] = email.Utils.formatdate( )

# 得到格式化后的完整文本
fullText = main_msg.as_string( )

# 用smtp发送邮件
try:
    server.sendmail(From, To, fullText)
finally:
    server.quit()
上面的代码只是发送邮件的大体代码,下面讲一下详细发送代码和注意事项:
一、gmail邮箱
发送代码如下:
#! /usr/bin/env python
#coding=utf-8
'''
发送邮件学习
'''
import smtplib, mimetypes
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.Header import Header
from email.Encoders import encode_base64
import os.path

def getAttachment(attachmentFilePath):  
    print 'get path:',attachmentFilePath
    contentType, encoding = mimetypes.guess_type(attachmentFilePath) 
    print  contentType, encoding

    if contentType is None or encoding is not None:  
        contentType = 'application/octet-stream'  

    mainType, subType = contentType.split('/', 1)
    print   mainType, subType
    file = open(attachmentFilePath, 'rb')  
    attachment = MIMEBase(mainType, subType)  
    attachment.set_payload(file.read())  
    encode_base64(attachment)    
    file.close()
    #下面设置附件的头  
    attachment.add_header('Content-Disposition', 'attachment ; filename="%s"' %attachmentFilePath.encode('gb2312')) 
    print "finish" 
    print attachment
    return attachment

def gmail_send(from_addr,to_addr,header,subject,username,password,msg_content,msg_type='plain',attachment=None):
    try:
        #构造邮件头部信息
        msg = MIMEMultipart()
        msg['From'] = from_addr
        msg['To'] = to_addr
        msg['Subject'] = Header(header,charset='UTF-8')
        print u"头部构造完成"

        #添加邮件内容,先判断是明文邮件内容还是html内容
        msg_type = msg_type.lower()
        if msg_type == 'plain':
            msg.attach(MIMEText(msg_content, _subtype='plain',  _charset='UTF-8'))
        elif msg_type == 'html':
            msg.attach(MIMEText(msg_content, _subtype='html',  _charset='UTF-8'))
        else:
            print u"不是有效的邮件内容类型"
            return False

        #添加邮件附件
        if attachment is not None:
            for att in attachment:
                msg.attach(getAttachment(att))
    except Exception,e:
        print u"构造邮件内容失败",e
        return False

    '''
    下面是gmail发送邮件过程
    '''
    try:
        smtp = smtplib.SMTP()
        smtp.set_debuglevel(1)
        smtp.connect('smtp.gmail.com',587)
        smtp.ehlo()
        smtp.starttls()
        smtp.ehlo()
        smtp.login(username,password)
        smtp.sendmail(from_addr, to_addr.split(','), msg.as_string())
        print u"发送成功"
        return True
    except smtplib.SMTPException,e:
        print u"由于SMTP原因发送失败",e
        return False
    except Exception,e:
        print u"发送失败",e
        return False
    finally:
        smtp.quit()
if __name__ == '__main__':
    #gmail_send('duhaizhang@gmail.com','1036914434@qq.com','这是中文邮件主题~~','测试','duhaizhang','wldroyogbwqzlqty','测试邮件正文','plain',u'K:\\安全协议概述.ppt')
    gmail_send('duhaizhang01@gmail.com','duhaizhang@gmail.com,1036914434@qq.com','这是中文邮件主题~~','测试','duhaizhang01','duhaizhang','测试邮件正文','plain',[u'杜.doc','baidu.txt'])
上面是gmail的发送代码,需要注意的内容有一下几点:
1、头部主题是中文时需要进行编码,编码是通过email.Header.Header()函数来进行的。因此,传入的主题参数不需要转换为unicode。
2、邮件内容分为两种,两种类型有点不同。
3、函数的附件路径需要传入时需加u转换为unicode是因为函数里面要读文件,而设置附件头的附件名称时需要将其重新编码。
4、gmail邮箱如果启用二次验证,会导致输入原始密码而提示口令错误,因此应该使用应用密码。
5、gmail对附件类型做了限制,限制不能上传包含有exe等危险附件,即使你压缩了也不行。
参考网站:PYTHON俱乐部:http://www.pythonclub.org
1、MIME邮件格式分析及信息提取  http://www.pythonclub.org/python-files/mime-type
2、Python SMTP 发送带附件电子邮件 http://www.pythonclub.org/python-network-application/smtp

转载请注明:jinglingshu的博客 » Python SMTP 发送带附件电子邮件


Warning: Use of undefined constant PRC - assumed 'PRC' (this will throw an Error in a future version of PHP) in /usr/share/nginx/html/wp-content/themes/d8/comments.php on line 17
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址