Python SMTP 发送带附件电子邮件
这里写链接内容可采用email模块发送电子邮件附件。发送一个未知MIME类型的文件附件其基本思路如下:1. 构造MIMEMultipart对象做为根容器2. 构造MIMEText对象做为邮件显示内容并附加到根容器3. 构造MIMEBase对象做为文件附件内容并附加到根容器 a. 读入文件内容并格式化 b. 设置附件头4. 设置根容器属性5. 得到格式化后的完整文本6. 用smtp发
可采用email模块发送电子邮件附件。发送一个未知MIME类型的文件附件其基本思路如下:
1. 构造MIMEMultipart对象做为根容器
2. 构造MIMEText对象做为邮件显示内容并附加到根容器
3. 构造MIMEBase对象做为文件附件内容并附加到根容器
a. 读入文件内容并格式化
b. 设置附件头
4. 设置根容器属性
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()
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()
以上内容转载于:http://www.cnblogs.com/alaska1131/articles/1852653.html
网上关于python的例子所涉及的知识比较烦杂,本着学习Python的心态,掌握发送邮件为知识点,并对代码进行比较分析,对发送邮件相关知识点逐步了解。以下是三段发送邮件代码,均测试成功。
代码一
- # -*- coding: utf-8 -*-
- import smtplib
- import email.MIMEMultipart# import MIMEMultipart
- import email.MIMEText# import MIMEText
- import email.MIMEBase# import MIMEBase
- import os.path
- import mimetypes
- From = ”发送邮箱”
- To = ”接收箱箱”
- file_name = ”c:/1.png”#附件名
- server = smtplib.SMTP(”smtp.163.com”)
- 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”,_charset=“utf-8”)
- main_msg.attach(text_msg)
- # 构造MIMEBase对象做为文件附件内容并附加到根容器
- ## 读入文件内容并格式化 [方式1]------------------------------
- data = open(file_name, ’rb’)
- ctype,encoding = mimetypes.guess_type(file_name)
- if ctype is None or encoding is not None:
- ctype = ’application/octet-stream’
- maintype,subtype = ctype.split(’/’,1)
- file_msg = email.MIMEBase.MIMEBase(maintype, subtype)
- file_msg.set_payload(data.read())
- data.close( )
- email.Encoders.encode_base64(file_msg)#把附件编码
- ””’
- 测试识别文件类型:mimetypes.guess_type(file_name)
- rar 文件 ctype,encoding值:None None(ini文件、csv文件、apk文件)
- txt text/plain None
- py text/x-python None
- gif image/gif None
- png image/x-png None
- jpg image/pjpeg None
- pdf application/pdf None
- doc application/msword None
- zip application/x-zip-compressed None
- encoding值在什么情况下不是None呢?以后有结果补充。
- ”’
- #---------------------------------------------
- ## 设置附件头
- 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()
# -*- coding: utf-8 -*-
import smtplib
import email.MIMEMultipart# import MIMEMultipart
import email.MIMEText# import MIMEText
import email.MIMEBase# import MIMEBase
import os.path
import mimetypes
From = "发送邮箱"
To = "接收箱箱"
file_name = "c:/1.png"#附件名
server = smtplib.SMTP("smtp.163.com")
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",_charset="utf-8")
main_msg.attach(text_msg)
构造MIMEBase对象做为文件附件内容并附加到根容器
读入文件内容并格式化 [方式1]------------------------------
data = open(file_name, 'rb')
ctype,encoding = mimetypes.guess_type(file_name)
if ctype is None or encoding is not None:
ctype = 'application/octet-stream'
maintype,subtype = ctype.split('/',1)
file_msg = email.MIMEBase.MIMEBase(maintype, subtype)
file_msg.set_payload(data.read())
data.close( )
email.Encoders.encode_base64(file_msg)#把附件编码
'''
测试识别文件类型:mimetypes.guess_type(file_name)
rar 文件 ctype,encoding值:None None(ini文件、csv文件、apk文件)
txt text/plain None
py text/x-python None
gif image/gif None
png image/x-png None
jpg image/pjpeg None
pdf application/pdf None
doc application/msword None
zip application/x-zip-compressed None
encoding值在什么情况下不是None呢?以后有结果补充。
'''
---------------------------------------------
设置附件头
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()
代码二
- # -*- coding: utf-8 -*-
- import smtplib
- import email.MIMEMultipart# import MIMEMultipart
- import email.MIMEText# import MIMEText
- import email.MIMEBase# import MIMEBase
- import os.path
- From = ”发送邮箱”
- To = ”接收箱箱”
- file_name = r”c:/1.png”#附件名
- server = smtplib.SMTP(”smtp.163.com”)
- 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”,_charset=“utf-8”)
- main_msg.attach(text_msg)
- # 构造MIMEBase对象做为文件附件内容并附加到根容器
- contype = ’application/octet-stream’
- maintype, subtype = contype.split(’/’, 1)
- ## 读入文件内容并格式化 [方式2]------------------------------
- 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()
# -*- coding: utf-8 -*-
import smtplib
import email.MIMEMultipart# import MIMEMultipart
import email.MIMEText# import MIMEText
import email.MIMEBase# import MIMEBase
import os.path
From = "发送邮箱"
To = "接收箱箱"
file_name = r"c:/1.png"#附件名
server = smtplib.SMTP("smtp.163.com")
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",_charset="utf-8")
main_msg.attach(text_msg)
构造MIMEBase对象做为文件附件内容并附加到根容器
contype = 'application/octet-stream'
maintype, subtype = contype.split('/', 1)
读入文件内容并格式化 [方式2]------------------------------
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()
代码三
- # -*- coding: utf-8 -*-
- import smtplib
- import email.MIMEMultipart# import MIMEMultipart
- import email.MIMEText# import MIMEText
- import email.MIMEBase# import MIMEBase
- import os.path
- import mimetypes
- import email.MIMEImage# import MIMEImage
- From = ”发送邮箱”
- To = ”接收箱箱”
- file_name = ”c:/1.png”#附件名
- server = smtplib.SMTP(”smtp.163.com”)
- 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”,_charset=“utf-8”)
- main_msg.attach(text_msg)
- # 构造MIMEBase对象做为文件附件内容并附加到根容器
- ctype,encoding = mimetypes.guess_type(file_name)
- if ctype is None or encoding is not None:
- ctype=’application/octet-stream’
- maintype,subtype = ctype.split(’/’,1)
- file_msg=email.MIMEImage.MIMEImage(open(file_name,’rb’).read(),subtype)
- print ctype,encoding
- ## 设置附件头
- 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()
# -*- coding: utf-8 -*-
import smtplib
import email.MIMEMultipart# import MIMEMultipart
import email.MIMEText# import MIMEText
import email.MIMEBase# import MIMEBase
import os.path
import mimetypes
import email.MIMEImage# import MIMEImage
From = "发送邮箱"
To = "接收箱箱"
file_name = "c:/1.png"#附件名
server = smtplib.SMTP("smtp.163.com")
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",_charset="utf-8")
main_msg.attach(text_msg)
构造MIMEBase对象做为文件附件内容并附加到根容器
ctype,encoding = mimetypes.guess_type(file_name)
if ctype is None or encoding is not None:
ctype='application/octet-stream'
maintype,subtype = ctype.split('/',1)
file_msg=email.MIMEImage.MIMEImage(open(file_name,'rb').read(),subtype)
print ctype,encoding
设置附件头
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()
相关知识介绍
mailMsg.set_payload(safe_unicode(bodyText).encode(charset), charset=none)
set_payload的参数说明:
参数1:安全二进制流,即文件数据
参数2:编码,默认为none
详情:http://nullege.com/codes/search/email.MIMEBase.MIMEBase.set_payload
知识点汇总:
如果用户A通过B邮箱来向C发送邮件。那么C收到邮件后,如果回复的话,回复的邮件地址是B邮箱。如果想要回复的邮箱是A邮箱,那么就要设置回复邮件的地址,通过python如何设置呢?设置的方法如下:
- main_msg[‘Reply-to’] = ‘对方回复的邮箱地址’
main_msg['Reply-to'] = '对方回复的邮箱地址'
2、对方收到邮件后显示发送邮件方的名称
一般情况下,采用这样的代码:
- main_msg[‘From’] = ‘10000@qq.com’
main_msg['From'] = '10000@qq.com'
对方看到的是该邮箱。如果还想显示用户名,采用如下代码:
- main_msg[‘From’]=“大头爸爸<10000@qq.com>”
main_msg['From']="大头爸爸<10000@qq.com>"
这样,收到邮件的人就会在邮箱收件人一栏中看到:大头爸爸<100000@qq.com>,而不仅仅显示邮箱的地址。
3、向多人发送邮件
1、一个情况是,如果我向多人发送邮件,但同时我不希望收到邮件的人知道我发给的人。这里就不能设置main_msg[‘To’],也不能设置main_msg[‘Cc’](抄送),因为用这两种方式发送,收件人获取邮件时,会列出所有收取该邮件的邮箱。这里只有采用密件的方式发送。即设置main_msg[‘Bcc’]。
2、向多人发送邮件,一定要注意:
- # 用smtp发送邮件
- try:
- server.sendmail(From, To.split(’;’), fullText)
- finally:
- server.quit()
# 用smtp发送邮件
try:
server.sendmail(From, To.split(';'), fullText)
finally:
server.quit()
sendmail中的那个To是list,不是string,否则只能发给第一个人。因为我传递的多个接收邮件的地址是用半角分号(;)分隔,所以我在这里转为list。
但是设置main_msg[‘Bcc’]时,他的值不能为list,而应该是string。如代码:
- main_msg[‘Bcc’]=To
main_msg['Bcc']=To
经过一翻测试,不设置main_msg[‘Bcc’]值也正常,且符合预期,即收件人在访问邮件时,收件人地址为空。如下图所示:
3、一个奇怪的乱码问题
因为我写的脚本编码保存为utf-8。通过QQ企业邮箱发送给网易邮箱时,邮件内容都很正常,如下图所示:
只是当收到邮件的用户回复时,出现部分内容乱码现象。如下图所示:
python邮件发送代码:
- # -*- coding: utf-8 -*-
- import smtplib
- import email.MIMEMultipart# import MIMEMultipart
- import email.MIMEText# import MIMEText
- import email.MIMEBase# import MIMEBase
- import os.path
- import sys
- import mimetypes
- import email.MIMEImage# import MIMEImage
- #命令 mail.py <1:发送方(回复地址)10000@qq.com> <2:发送地址,多个以;隔开> <3:发送文件>
- From =”合肥顶击科技<itop_business@5186.me>”
- ReplyTo=sys.argv[1]
- To = sys.argv[2]
- file_name = sys.argv[3]#附件名
- server = smtplib.SMTP(”smtp.exmail.qq.com”,25)
- server.login(”itop_business@5186.me”,“xxxxxxx”) #仅smtp服务器需要验证时
- # 构造MIMEMultipart对象做为根容器
- main_msg = email.MIMEMultipart.MIMEMultipart()
- # 构造MIMEText对象做为邮件显示内容并附加到根容器
- text_msg = email.MIMEText.MIMEText(”顶击拨号帮你转发的邮件”,_charset=“utf-8”)
- main_msg.attach(text_msg)
- # 构造MIMEBase对象做为文件附件内容并附加到根容器
- ctype,encoding = mimetypes.guess_type(file_name)
- if ctype is None or encoding is not None:
- ctype=’application/octet-stream’
- maintype,subtype = ctype.split(’/’,1)
- file_msg=email.MIMEImage.MIMEImage(open(file_name,’rb’).read(),subtype)
- ## 设置附件头
- 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[’Reply-to’] = ReplyTo
- #main_msg[‘To’] = To
- main_msg[’Subject’] = “亲,你朋友给你发送的邮件-顶击科技有限公司转发”
- main_msg[’Date’] = email.Utils.formatdate()
- #main_msg[‘Bcc’] = To
- # 得到格式化后的完整文本
- fullText = main_msg.as_string( )
- # 用smtp发送邮件
- try:
- server.sendmail(From, To.split(’;’), fullText)
- finally:
- server.quit()
# -*- coding: utf-8 -*-
import smtplib
import email.MIMEMultipart# import MIMEMultipart
import email.MIMEText# import MIMEText
import email.MIMEBase# import MIMEBase
import os.path
import sys
import mimetypes
import email.MIMEImage# import MIMEImage
命令 mail.py <1:发送方(回复地址)10000@qq.com> <2:发送地址,多个以;隔开> <3:发送文件>
From ="合肥顶击科技<itop_business@5186.me>"
ReplyTo=sys.argv[1]
To = sys.argv[2]
file_name = sys.argv[3]#附件名
server = smtplib.SMTP("smtp.exmail.qq.com",25)
server.login("itop_business@5186.me","xxxxxxx") #仅smtp服务器需要验证时
构造MIMEMultipart对象做为根容器
main_msg = email.MIMEMultipart.MIMEMultipart()
构造MIMEText对象做为邮件显示内容并附加到根容器
text_msg = email.MIMEText.MIMEText("顶击拨号帮你转发的邮件",_charset="utf-8")
main_msg.attach(text_msg)
构造MIMEBase对象做为文件附件内容并附加到根容器
ctype,encoding = mimetypes.guess_type(file_name)
if ctype is None or encoding is not None:
ctype='application/octet-stream'
maintype,subtype = ctype.split('/',1)
file_msg=email.MIMEImage.MIMEImage(open(file_name,'rb').read(),subtype)
设置附件头
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['Reply-to'] = ReplyTo
main_msg['To'] = To
main_msg['Subject'] = "亲,你朋友给你发送的邮件-顶击科技有限公司转发"
main_msg['Date'] = email.Utils.formatdate()
main_msg['Bcc'] = To
得到格式化后的完整文本
fullText = main_msg.as_string( )
用smtp发送邮件
try:
server.sendmail(From, To.split(';'), fullText)
finally:
server.quit()
修改内容如下:
首先,在头部增加:
- from email.header import Header
from email.header import Header
1、将“合肥顶击科技”转为utf-8
- From = “%s<itop_business@5186.me>” % Header(“合肥顶击科技”,“utf-8”)
From = "%s<itop_business@5186.me>" % Header("合肥顶击科技","utf-8")
结果如下:
2、在内容前面加个u
- main_msg[‘Subject’] = u“亲,你朋友给你发送的邮件-顶击科技有限公司转发”
main_msg['Subject'] = u"亲,你朋友给你发送的邮件-顶击科技有限公司转发"
或者转为utf-8
- Header(“hello,亲,你朋友给你发送的邮件-顶击科技有限公司转发”,“utf-8”)
Header("hello,亲,你朋友给你发送的邮件-顶击科技有限公司转发","utf-8")
现在一切OK,如下图所示:
至此,乱码问题全部解决。上面这个问题是在163邮箱中出现的问题,如果接收邮箱为QQ邮箱,没有发现回复时出现乱码问题。
更多推荐
所有评论(0)