Python使用smtplib和email模块发送各类邮件详解
本文详细介绍Python中利用smtplib和email模块发送邮件的方法。涵盖普通文本、HTML、带附件及图片邮件的实现代码。解析SMTP连接、登录验证及消息构造过程,提供Python 2.6环境下的完整示例,帮助开发者掌握邮件发送核心技巧。
Python内置的email模块大幅简化了邮件处理流程。本文重点梳理发送邮件的具体操作步骤,分享实践心得,并欢迎技术专家提供指导与建议。
一、相关模块介绍
发送邮件主要依赖smtplib和email两个核心模块,下文将对这两个模块进行简要概述。
1、smtplib模块
smtplib.SMTP([host[, port[, local_hostname[, timeout]]]])
SMTP类构造函数用于建立与SMTP服务器的连接。通过该连接可向服务器发送指令,执行登录、发送邮件等操作。所有参数均为可选。
host:指定SMTP服务器的主机名。
port:指定SMTP服务的端口号,默认值为25。若在创建SMTP对象时提供了host和port参数,初始化阶段会自动调用connect方法连接服务器。
smtplib模块还包含SMTP_SSL类和LMTP类,其操作方式与SMTP类基本一致。
smtplib.SMTP提供的主要方法如下:
SMTP.set_debuglevel(level):用于设置调试模式。默认值为False(非调试模式),即不输出任何调试信息。
SMTP.connect([host[, port]]):连接指定的SMTP服务器。参数分别代表SMTP主机和端口。注意:也可以在host参数中直接指定端口号(例如:smtp.yeah.net:25),此时无需单独提供port参数。
SMTP.docmd(cmd[, argstring]):向SMTP服务器发送指令。可选参数argstring表示该指令所需的参数。
SMTP.helo([hostname]):使用“helo”指令向服务器确认身份,相当于告知SMTP服务器“我是谁”。
SMTP.has_extn(name):判断指定名称是否存在于服务器的邮件列表中。出于安全考虑,多数SMTP服务器已屏蔽此指令。
SMTP.verify(address):判断指定的邮件地址是否在服务器中存在。出于安全考虑,多数SMTP服务器已屏蔽此指令。
SMTP.login(user, password):登录到SMTP服务器。目前几乎所有SMTP服务器都要求先验证用户信息合法,之后才允许发送邮件。
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]):执行邮件发送。需注意第三个参数msg为字符串,代表邮件内容。邮件通常由标题、发件人、收件人、正文及附件等构成,发送时需确保msg符合SMTP协议定义的格式。
SMTP.quit():断开与SMTP服务器的连接,相当于发送“quit”指令。(注:许多程序中使用了smtp.close(),关于其与quit()的具体区别,经查阅资料暂未找到明确解释。)
2、email模块
email模块用于处理邮件消息,包括MIME及其他基于RFC 2822标准的消息文档。利用这些模块定义邮件内容十分简便。其包含的类有(更详细介绍可见:http://docs.python.org/library/email.mime.html):
class email.mime.base.MIMEBase(_maintype, _subtype, **_params):这是MIME的一个基类,通常无需在创建实例时手动调用。其中_maintype指内容类型(如text或image),_subtype指内容的次要类型(如plain或gif)。**_params是一个字典,直接传递给Message.add_header()。
class email.mime.multipart.MIMEMultipart([_subtype[, boundary[, _subparts[, _params]]]]):MIMEBase的一个子类,用于表示多个MIME对象的集合,_subtype默认值为mixed。boundary是MIMEMultipart的边界,默认边界为可数。
class email.mime.application.MIMEApplication(_data[, _subtype[, _encoder[, **_params]]]):MIMEMultipart的一个子类。
class email.mime.audio.MIMEAudio(_audiodata[, _subtype[, _encoder[, **_params]]]):MIME音频对象。
class email.mime.image.MIMEImage(_imagedata[, _subtype[, _encoder[, **_params]]]):MIME二进制文件对象。
class email.mime.message.MIMEMessage(_msg[, _subtype]):具体的一个message实例,使用方法如下:
msg=mail.Message.Message() #一个实例 msg['to']='XXX@XXX.com' #发送到哪里 msg['from']='YYY@YYYY.com' #自己的邮件地址 msg['date']='2012-3-16' #时间日期 msg['subject']='hello world' #邮件主题
class email.mime.text.MIMEText(_text[, _subtype[, _charset]]):MIME文本对象。其中_text为邮件内容,_subtype为邮件类型(可以是text/plain普通文本邮件,或html/plain HTML邮件),_charset为编码方式(如gb2312等)。
二、几种邮件的具体实现代码
1、普通文本邮件
发送普通文本邮件的关键在于将MIMEText中的_subtype设置为plain。首先需要导入smtplib和mimetext模块。创建smtplib.smtp实例,连接邮件SMTP服务器,登录成功后发送,具体代码如下:(基于Python 2.6实现)
# -*- coding: UTF-8 -*-
'''
发送txt文本邮件
'''
import smtplib
from email.mime.text import MIMEText
mailto_list=[YYY@YYY.com]
mail_host="smtp.XXX.com" #设置服务器
mail_user="XXXX" #用户名
mail_pass="XXXXXX" #口令
mail_postfix="XXX.com" #发件箱的后缀
def send_mail(to_list,sub,content):
me="hello"+"<"+mail_user+"@"+mail_postfix+">"
msg = MIMEText(content,_subtype='plain',_charset='gb2312')
msg['Subject'] = sub
msg['From'] = me
msg['To'] = ";".join(to_list)
try:
server = smtplib.SMTP()
server.connect(mail_host)
server.login(mail_user,mail_pass)
server.sendmail(me, to_list, msg.as_string())
server.close()
return True
except Exception, e:
print str(e)
return False
if __name__ == '__main__':
if send_mail(mailto_list,"hello","hello world!"):
print "发送成功"
else:
print "发送失败"
2、html邮件的发送
与文本邮件的区别在于,将MIMEText中的_subtype设置为html。具体代码如下:(基于Python 2.6实现)
# -*- coding: utf-8 -*-
'''
发送html文本邮件
'''
import smtplib
from email.mime.text import MIMEText
mailto_list=["YYY@YYY.com"]
mail_host="smtp.XXX.com" #设置服务器
mail_user="XXX" #用户名
mail_pass="XXXX" #口令
mail_postfix="XXX.com" #发件箱的后缀
def send_mail(to_list,sub,content): #to_list:收件人;sub:主题;content:邮件内容
me="hello"+"<"+mail_user+"@"+mail_postfix+">" #这里的hello可以任意设置,收到信后,将按照设置显示
msg = MIMEText(content,_subtype='html',_charset='gb2312') #创建一个实例,这里设置为html格式邮件
msg['Subject'] = sub #设置主题
msg['From'] = me
msg['To'] = ";".join(to_list)
try:
s = smtplib.SMTP()
s.connect(mail_host) #连接smtp服务器
s.login(mail_user,mail_pass) #登陆服务器
s.sendmail(me, to_list, msg.as_string()) #发送邮件
s.close()
return True
except Exception, e:
print str(e)
return False
if __name__ == '__main__':
if send_mail(mailto_list,"hello","<a href='http://www.cnblogs.com/xiaowuyi'>小五义</a>"):
print "发送成功"
else:
print "发送失败"
3、发送带附件的邮件
发送带附件的邮件时,首先要创建MIMEMultipart()实例,然后构造附件。若有多个附件,可依次构造,最后利用smtplib.smtp进行发送。
# -*- coding: cp936 -*-
'''
发送带附件邮件
'''
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
#创建一个带附件的实例
msg = MIMEMultipart()
#构造附件1
att1 = MIMEText(open('d:\\123.rar', 'rb').read(), 'base64', 'gb2312')
att1["Content-Type"] = 'application/octet-stream'
att1["Content-Disposition"] = 'attachment; filename="123.doc"'#这里的filename可以任意写,写什么名字,邮件中显示什么名字
msg.attach(att1)
#构造附件2
att2 = MIMEText(open('d:\\123.txt', 'rb').read(), 'base64', 'gb2312')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="123.txt"'
msg.attach(att2)
#加邮件头
msg['to'] = 'YYY@YYY.com'
msg['from'] = 'XXX@XXX.com'
msg['subject'] = 'hello world'
#发送邮件
try:
server = smtplib.SMTP()
server.connect('smtp.XXX.com')
server.login('XXX','XXXXX')#XXX为用户名,XXXXX为密码
server.sendmail(msg['from'], msg['to'],msg.as_string())
server.quit()
print '发送成功'
except Exception, e:
print str(e)
4、利用MIMEimage发送图片
# -*- coding: cp936 -*-
import smtplib
import mimetypes
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
def AutoSendMail():
msg = MIMEMultipart()
msg['From'] = "XXX@XXX.com"
msg['To'] = "YYY@YYY.com"
msg['Subject'] = "hello world"
txt = MIMEText("这是中文的邮件内容哦",'plain','gb2312')
msg.attach(txt)
file1 = "C:\\hello.jpg"
image = MIMEImage(open(file1,'rb').read())
image.add_header('Content-ID','<image1>')
msg.attach(image)
server = smtplib.SMTP()
server.connect('smtp.XXX.com')
server.login('XXX','XXXXXX')
server.sendmail(msg['From'],msg['To'],msg.as_string())
server.quit()
if __name__ == "__main__":
AutoSendMail()
利用MIMEimage发送图片时,初衷是希望图片能在正文中直接显示。但代码运行后发现,图片仍以附件形式发送。此处希望有高手指点,如何实现在正文中显示图片(即图片作为附件存在,同时能在正文中展示),具体形式如下图。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













