Python 第三方模块之 smtplib

一、python对SMTP的支持

SMTP(Simple Mail Transfer Protocol)是简单传输协议,它是一组用于用于由源地址到目的地址的邮件传输规则。

python中对SMTP进行了简单的封装,可以发送纯文本邮件、HTML邮件以及带附件的邮件。两个核心模块如下:

  • email模块:负责构建邮件
  • smtplib模块:负责发送邮件

1、创建SMTP对象

import smtplib
smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
# smtpObj = smtplib.SMTP_SSL( [host [, port [, local_hostname]]] )

参数说明:
    host: SMTP 服务器主机。 你可以指定主机的ip地址或者域名如: runoob.com,这个是可选参数。
    port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号,一般情况下 SMTP 端口号为25。
    local_hostname: 如果 SMTP 在你的本机上,你只需要指定服务器地址为 localhost 即可。 


#################### 示例一
smtp = smtplib.SMTP()
smtp.connect([host[,port]])  # 连接远程smtp主机方法,host为远程主机地址,port为远程主机smtp端口,默认为25,也可以直接使用host:port形式来表示,例如:SMTP.connect("smtp.163.com","25")
smtp.starttls()                       # 开启安全传输模式
smtp.login("[email protected]","pwd") # 邮箱账号登录校验
smtp.sendmail(FROM, [TO], BODY)       # 邮件发送
smtp.quit()                           # 断开smtp连接

#################### 示例二
smtp = smtplib.SMTP([host[,port]])
smtp.login("[email protected]","pwd") # 邮箱账号登录校验
smtp.set_debuglevel(1)                # 打印出和SMTP服务器交互的所有信息。
smtp.sendmail(FROM, [TO], BODY)       # 邮件发送
smtp.quit()                           # 断开smtp连接

2、SMTP对象使用sendmail方法发送邮件:

SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options])  # from_addr: 邮件发送者地址。to_addrs: 字符串列表,邮件发送地址。msg: 发送消息 

这里要注意一下第三个参数,msg 是字符串,表示邮件。我们知道邮件一般由标题,发信人,收件人,邮件内容,附件等构成,发送邮件的时候,要注意 msg 的格式。这个格式就是 smtp 协议中定义的格式。

SMTP类有几个常用的方法:

方法

描述

SMTP.set_debuglevel(level) 设置输出debug调试信息,默认不输出
SMTP.docmd(cmd[, argstring]) 发送一个命令到SMTP服务器
SMTP.connect([host[, port]]) 连接到指定的SMTP服务器
SMTP.helo([hostname]) 使用helo指令向SMTP服务器确认你的身份
SMTP.ehlo(hostname) 使用ehlo指令像ESMTP(SMTP扩展)确认你的身份
SMTP.ehlo_or_helo_if_needed() 如果在以前的会话连接中没有提供ehlo或者helo指令,这个方法会调用ehlo()或helo()
SMTP.has_extn(name) 判断指定名称是否在SMTP服务器上
SMTP.verify(address) 判断邮件地址是否在SMTP服务器上
SMTP.starttls([keyfile[, certfile]]) 使SMTP连接运行在TLS模式,所有的SMTP指令都会被加密
SMTP.login(user, password) 登录SMTP服务器
SMTP.sendmail(from_addr, to_addrs, msg, mail_options=[], rcpt_options=[])

发送邮件

from_addr:邮件发件人

to_addrs:邮件收件人

msg:发送消息

SMTP.quit() 关闭SMTP会话
SMTP.close() 关闭SMTP服务器连接
  • email模块:支持发送的邮件内容为纯文本,HTML内容,图片,附件。email模块中有几类来针对不同的邮件内容形式,常用如下:
  • MIMEText : (MIME媒体类型)内容形式为纯文本,HTML页面(导入方式 : from email.mime.text import MIMEText)
  • MIMEImage : 内容形式为图片(导入方式 : from email.mime.image import MIMEImage)
  • MIMEMultupart : 多形式组合,可包含文本和附件(导入方式 : from email.mime.multipart import MIMEMultipart)

.MIMEText语法:

MIMEText(msg,type,chartset)
    msg:文本内容
    type:文本类型默认为plain(纯文本)#发送HTML格式的时候,修改为html,但同时要求msg的内容也是html的格式。
    chartset:文本编码,中文为“utf-8”

# 构造TEXT格式的消息
  msg = MIMEText("hello.text","plain","utf-8")
  msg["Subject"] = "xxxxx"
  msg["From"] = "xxxx"
  msg["To"] = "xxxx"

# 发送以上构造的邮件内容要使用as_string将构造的邮件内容转换为string形式。
  s.sendmail("xxx","xxx",msg.as_string)

2.MIMEImage,MIMEMultipart语法

msg = MIMEMultipart()

# 实例化一个文本对象 
msg_sub = MIMEText("hello.text","plain","utf-8")

# 将text消息添加到MIMEMultipart中,作为邮件正文。
msg.attach(msg_sub)

# 图片作为附件
import os
img_datas = open(os.getcwd()+ "/reports/xxxx.png","rb").read()
msg_img = MIMEImage(img_data)
msg_img.add_header('Content-Disposition','attachment', filename = "xxxx.png" )
msg_img.add_header('Content-ID','<0>')

# 将图片添加到MIMEMultiplart中,作为附件发送。
msg.attach(mag_img)

二、可以发送不同格式的邮件

发送文本邮件

# coding=utf-8
import smtplib
from email.mime.text import MIMEText


sender = '[email protected]'  # 发送邮箱地址
password = 'xxxxxxx'        # 邮箱授权码,非登陆密码
mailto_list = ['[email protected]']  # 群发邮箱地址
smtp_server = 'smtp.163.com'  # smtp服务器

# 发送纯文本格式的邮件
msg = MIMEText('hello,send by python_test...','plain','utf-8')
msg['From'] = sender                   # 发送邮箱地址
msg['To'] =';'.join(mailto_list)       # 发送多人邮件写法
msg['Subject'] = 'hello,i just want to test'  # 主题

server = smtplib.SMTP(smtp_server,25)  # SMTP协议默认端口是25
server.login(sender,password)          # login()方法用来登录SMTP服务器
server.set_debuglevel(1)               # 打印出和SMTP服务器交互的所有信息。
server.sendmail(sender,mailto_list,msg.as_string()) # msg.as_string()把MIMEText对象变成str server.quit()
# 第一个参数为发送者,第二个参数为接收者,可以添加多个例如:['[email protected]','[email protected]',]# 第三个参数为发送的内容
server.quit()

Python 第三方模块之 smtplib_第1张图片

查看和SMTP服务器交互的所有信息:

Python 第三方模块之 smtplib_第2张图片

其中login()用来登陆SMTP服务器,sendmail()用来发送邮件,群发邮件的话,可以传入一个收件人邮箱列表,邮箱的正文是str,使用as_string()把MIMEText对象变成str,password指的不是smtp服务器的登陆密码,是smtp客户端的授权密码:

Python 第三方模块之 smtplib_第3张图片

发送带HTML的邮件:

import smtplib
from email.mime.text import MIMEText
from email.header import Header


sender = '[email protected]'        # 发件邮箱
passwd = 'xxxxxxxx'               # 发送人邮箱授权码
receivers = '[email protected]'   # 收件邮箱
subject = 'python发邮Html邮件测试' # 主题

content = "

人生苦短,何必执着

" msg = MIMEText(content,'html','utf-8') msg['Subject'] = Header(subject,'utf-8') # msg['Subject'] = subject msg['From'] = Header('hello','utf-8') # msg['From'] = sender msg['To'] = Header('emmmm','utf-8') # msg['To'] = receivers try: s = smtplib.SMTP_SSL('smtp.163.com',25) s.login(sender,passwd) s.sendmail(sender,receivers,msg.as_string()) print('Send Success') except: print('Send Failure')

发送带图片附件的邮件:

import smtplib
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart


sender = '[email protected]'
passwd = 'xxxxxxxx'
receivers = '[email protected]'
subject = 'python发邮带img的邮件测试' 

# 创建一个带附件的实例
msg = MIMEMultipart()
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receivers

# 创建正文
msg.attach(MIMEText('使用python smtplib模块和email模块自动发送邮件测试','plain','utf-8'))

# 创建图片附件
import os
img_file = open(os.getcwd()+"/a4.jpg",'rb').read()
msg_img = MIMEImage(img_file)
msg_img.add_header('Content-Disposition','attachment', filename = "a4.jpg")
msg_img.add_header('Content-ID', '<0>')
msg.attach(msg_img)

try:
    s = smtplib.SMTP('smtp.163.com',25)
    s.set_debuglevel(1) # 输出发送邮件详细过程
    s.login(sender,passwd)
    s.sendmail(sender,receivers,msg.as_string())
    print('Send Succese')

except:
    print('Send Failure')

发送带附件的邮件:

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

sender = '[email protected]'   # 发件邮箱
passwd = 'xxxxxxxxxx'        # 邮箱授权码
receivers = '[email protected]' # 收件邮箱
subject = 'python发带附件的邮件测试' 
msg = MIMEMultipart()          # 创建一个带附件的实例 
msg['Subject'] = subject
msg['From'] = sender
msg['To'] = receivers

# 创建正文,将文本文件添加到MIMEMultipart中
msg.attach(MIMEText('使用python smtplib模块和email模块自动发送邮件测试','plain','utf-8'))

# 构造附件1,传送当前目录下文件
att1 = MIMEText(open('testdata.xlsx','rb').read(),'base64','utf-8') # rb以二进制方式读取
# att1["Content-Type"] = 'application/octet-stream'
# filename为附件名称,可以任意写,写什么名字,邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename = "testdata.xlsx" '
#将附件添加到MIMEMultipart中
msg.attach(att1)

#构造附件2
att2 = MIMEText(open('db.cfg','rb').read(),'base64','utf-8')
# att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename = "db.cfg" '
#将附件添加到MIMEMultipart中
msg.attach(att2)

try:
    s = smtplib.SMTP('smtp.qq.com',25)
    s.set_debuglevel(1) # 输出发送邮件详细过程
    s.login(sender,passwd)
    s.sendmail(sender,receivers,msg.as_string())
    print('Send Succese')

except:
    print('Send Failure')

发送HTML与图片格式的邮件

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.image import MIMEImage

sender = '[email protected]'      # 这里就是你的163邮箱
receiver = '[email protected]'     # 发给单人时的邮件接收邮箱
smtpserver = "smtp.163.com" # 邮件服务器,如果是163邮箱那就是这个了,其他的可以自行查找
username = '[email protected]'   # 这里还是你的邮箱
password = 'xxxxx'          # 上面获取的SMTP授权码,相当于是一个密码验证
msgRoot = MIMEMultipart('related') # 邮件类型,如果要加图片等附件,就得是这个
msgRoot['Subject'] = '监控日报'     # 邮件标题,以下设置项都很明了
msgRoot['From'] = sender
msgRoot['To'] = receiver

# 以下为邮件正文内容,含有一个居中的标题和一张图片
content = MIMEText('
我是居中显示的标题
image1','html','utf-8') # 如果有编码格式问题导致乱码,可以进行格式转换: # content = content.decode('utf-8').encode('gbk') msgRoot.attach(content) # 上面添加的图片src必须是cid:xxx的形式,xxx就是下面添加图片时设置的图片id fp = open('D:\\Desktop\\aaa.jpg', 'rb') msgImage = MIMEImage(fp.read()) fp.close() msgImage.add_header('Content-ID', 'image') # 这个id用于上面html获取图片 msgRoot.attach(msgImage) # 再加一个 fp1 = open('D:\\Desktop\\bbb.jpg', 'rb') msgImage1 = MIMEImage(fp1.read()) fp1.close() msgImage1.add_header('Content-ID', 'image1') # 这个id用于上面html获取图片 msgRoot.attach(msgImage1) ''' # 另外也可以用base64的方法直接加,但是这种方式outlook不支持 import base64 img_file = open('C:\\Users\\cloudoxou\\Desktop\\img.png','rb') base64_data = base64.b64encode(img_file.read()) html = "image1"%(base64_data) # 这里简化了html代码 ''' # 连接邮件服务器,因为使用SMTP授权码的方式登录,必须是994端口 smtp = smtplib.SMTP_SSL(smtpserver,994) smtp.login(username, password) smtp.sendmail(sender, receiver, msgRoot.as_string())

msg中输入的是邮件正文,因此需要根据具体内容格式选择合适的类型!

关于不同类型文件的对应类型,可参考此链接:HTTP Content-type 对照表。

MIMEMultipart类型

MIME邮件中各种不同类型的内容是分段存储的,各个段的排列方式、位置信息都通过Content-Type域的multipart类型来定义。multipart类型主要有三种子类型:mixed、alternative、related。

● MIMEMultipart(‘mixed’)类型
如果一封邮件中含有附件,那邮件的中必须定义multipart/mixed类型,邮件通过multipart/mixed类型中定义的boundary标识将附件内容同邮件其它内容分成不同的段。基本格式如下:msg=MIMEMultipart(‘mixed’)

● MIMEMultipart(‘alternative’)类型
MIME邮件可以传送超文本内容,但出于兼容性的考虑,一般在发送超文本格式内容的同时会同时发送一个纯文本内容的副本,如果邮件中同时存在纯文本和超文本内容,则邮件需要在Content-Type域中定义multipart/alternative类型,邮件通过其boundary中的分段标识将纯文本、超文本和邮件的其它内容分成不同的段。基本格式如下:msg=MIMEMultipart(‘alternative’)

● MIMEMultipart(‘related’)类型
MIME邮件中除了可以携带各种附件外,还可以将其它内容以内嵌资源的方式存储在邮件中。比如我们在发送html格式的邮件内容时,可能使用图像作为 html的背景,html文本会被存储在alternative段中,而作为背景的图像则会存储在multipart/related类型定义的段中。基本格式如下:msg=MIMEMultipart(‘related’)

 

你可能感兴趣的:(Python)