python stmp 定时发送邮件

一、定时发送

  • 安装schedule模块: pip install schedule

然后就是代码了:

import schedule
import time
#引入schedule和time

def job():
    print("宇宙最帅...")
#定义一个叫job的函数,函数的功能是打印'I'm working...'

schedule.every(10).minutes.do(job)       #部署每10分钟执行一次job()函数的任务
schedule.every().hour.do(job)            #部署每×小时执行一次job()函数的任务
schedule.every().day.at("10:30").do(job) #部署在每天的10:30执行job()函数的任务
schedule.every().monday.do(job)          #部署每个星期一执行job()函数的任务
schedule.every().wednesday.at("13:15").do(job)#部署每周三的13:15执行函数的任务

# 将帅进行到底,循环
while True:
    schedule.run_pending()
   # 帅也挺累的,休息1秒后再一次“帅”
    time.sleep(1)    

二、发送邮箱
1.smtplib模块实现邮件的发送功能,模拟一个stmp客户端,通过与smtp服务器交互来实现邮件发送的功能,可以理解成Foxmail的发邮件功能,在使用之前我们需要准备smtp服务器主机地址、邮箱账号以及密码信息。

在python2.3以后python自带smtplib模块,无需额外安装。

class smtplib.SMTP(host="",port=0,local_hostname=None,[timeout,]source_address=None):

SMTP类定义作为SMTP的构造函数,定义了一个SMTP客户端会话对象,功能是与smtp服务器建立链接,在链接成功后,就可以向服务器发送相关请求,比如登陆、校验、发送、退出等。

host:参数为远程smtp主机地址;如:smtp.163.com
port:为链接端口默认为25
local_hostname:是将本地主机的FQDN(完整域名)发送 HELO/EHLO(标识用户身份)的指令
timeout:为链接或尝试链接多少秒后超时
source_address:绑定到具有多个网络接口的计算机中的某个特定源地址上或特定的TCP端口,它需要一个元组(主机,端口)
SMTP类方法:

SMTP.connect(host=‘localhost’,port=0) :链接到远程SMTP主机的方法,host为远程主机地址,port为远程主机smtp端口,默认为25,也可以直接使用host:port形式来表示:如:SMTP.connect(‘smtp.163.com’,‘25’)

SMTP.login(user,password):登陆需要认证的SMTP服务器,参数为用户名与密码,如SMTP.login(‘[email protected]’,‘123’)

SMTP.sendmail(from_addr,to_addrs,msg,mail_options=[],rcpt_options=[]):实现邮件的发送功能,参数from_addr为发件人,to_addrs为收件人,msg为邮件内容,如:SMTP.sendmail(‘[email protected]’,‘[email protected]’,body)。

SMTP.starttls(keyfile=None,certfile=None):启用TLS安全传输模式,所有SMTP指令都将加密传输,如使用gmail的smtp服务时需哟啊启动此项才能正常发送邮件。

SMTP.quit():断开smtp服务器链接

SMTP.set_debuglevel(level):设置调试输出级别,值为1,2或True,发送调试消息到服务器

SMTP.send_message(msg,from_addr=None,to_addrs=None,mail_options=[],rcpt_options=[]):这是使用有email.message.Message对象表示的消息进行调用的便捷方法使用sendmail(),参数的含义与sendmail()相同,只有msg是一个Message对象;如果from_addr是None或者to_addrs是None,则send_message用从msg头部提取的地址填充那些参数,from设置为发件人自动,TO设置为to_addrs。

2.通过邮件传输简单的文本已经无法满足我们的需求,比如我们时常会定制业务质量报表,在邮件主体中会包含 HTML、图像、声音以及附件格式等,MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)作为一种新的扩展邮件格式很好地补充了这一点,更多MIME 知识见 https://docs.python.org/3/library/email.html。下面介绍几个 Python 中常用的 MIME 实现类:

email.mime.base.MIMEBase(_maintype,_subtype,*,policy = compat32,** _ params ):

这是所有MIME特定类的基类,_maintpe是Content-Type主要类型(text or image),_subtype是Content-Type次要类型(plain or gif),_params是一个键值字典参数直接传递给Message.add_header

3.email.mime.multipart.MIMEMultipart(_subtype=‘mixed’,boundary= None,_subparts = None,*,policy = compat32,** _ params ):
作用是生成包含多个部分的邮件体的 MIME 对象,参数 _subtype 指定要添加到"Content-type:multipart/subtype" 报头的可选的三种子类型,分别为 mixed、related、alternative,默认值为 mixed。定义 mixed实现构建一个带附件的邮件体;定义related 实现构建内嵌资源的邮件体;定义alternative 则实现构建纯文本与超文本共存的邮件体;_subparts是有效负载的一系类初始部分,可以使用attach()方法将子部件附加到消息中。

4.MIME实例对象的方法:

as_string() :返回字符串信息,相当于__str__(),str(msg)
as_bytes() :返回字节信息,相当于__bytes__(),bytes(msg)
is_multipart() :判断是否为有效载荷的列表message对象,是返回True,否则返回False
set_unixfrom(unixfrom) :将消息的信封头设置为unixfrom为字符串
get_unixfrom() :返回消息的信封头。默认为None
attach(payload) :将给定的有效负载添加到当前有效负载
get_payload(i=None, decode=False) :返回当前的有效载荷,这将是一个列表 Message
set_payload(payload, charset=None) :将整个消息对象的有效载荷设置为有效载荷
set_charset(charset) ;将有效负载的字符集设置为charset
get_charset() :返回Charset与消息有效负载相关的实例
len() :返回标题的总数,包括重复项
contains(name) :如果消息对象具有名为name的字段,则返回true
getitem(name) :返回指定标题字段的值
setitem(name, val) :将字段添加到带有字段名称和值val的消息中
delitem(name) :从消息的标题中删除所有出现的具有名称name的字段
keys() :返回所有消息标题字段名称的列表
values() :返回所有消息字段值的列表
items() :返回包含所有消息的字段标题和值
add_header(_name, _value, **_params) :扩展标题设置,_name为要添加的标题字段,_value为标题的值。

from email.mime.multipart import MIMEMultipart

msg1 = MIMEMultipart('mixed')  #创建带附件的实例
msg2 = MIMEMultipart('related')  #创建内嵌资源的实例
msg3 = MIMEMultipart('alternative') #创建纯文本与超文本实例
import smtplib 
#smtplib是python的一个内置库,所以不需要用pip安装
mailhost='smtp.qq.com'
#把qq邮箱的服务器地址赋值到变量mailhost上
qqmail = smtplib.SMTP()
#实例化一个smtplib模块里的SMTP类的对象,这样就可以SMTP对象的方法和属性了
qqmail.connect(mailhost,25)
#连接服务器,第一个参数是服务器地址,第二个参数是SMTP端口号。
#以上,皆为连接服务器的代码

account = input('请输入你的邮箱:')
#获取邮箱账号
password = input('请输入你的密码:')
#获取邮箱密码
qqmail.login(account,password)
#登录邮箱,第一个参数为邮箱账号,第二个参数为邮箱密码    

receiver=input('请输入收件人的邮箱:')
#获取收件人的邮箱

from email.mime.text import MIMEText
from email.header import Header
#引入Header和MIMEText模块
content=input('请输入邮件正文:')
#输入你的邮件正文
message = MIMEText(content, 'plain', 'utf-8')
#实例化一个MIMEText邮件对象,该对象需要写进三个参数,分别是邮件正文,文本格式和编码.
subject = input('请输入你的邮件主题:')
#用input()获取邮件主题  
message['Subject'] = Header(subject, 'utf-8')
#在等号的右边,是实例化了一个Header邮件头对象,该对象需要写入两个参数,分别是邮件主题和编码,然后赋值给等号左边的变量message['Subject']。

qqmail.sendmail(sender, receiver, message.as_string())
#发送邮件,调用了sendmail()方法,写入三个参数,分别是发件人,收件人,和字符串格式的正文。
try:
2     qqmail.sendmail(sender, receiver, message.as_string())
3     print ('邮件发送成功')
4 except:
5     print ('邮件发送失败')
qqmail.quit()
#退出邮箱

三、总结
各种邮件格式

import smtplib
from email.utils import make_msgid,formatdate
from email.mime.text import MIMEText #html格式和文本格式邮件
from email.mime.multipart import MIMEMultipart #带多个部分的邮件
from email.mime.image import MIMEImage #带图片格式邮件
from email.mime.audio import MIMEAudio  #音频文件对象
from email.utils import formataddr   #分隔标题与地址
from email.header import Header   #设置标题字符集
from email import encoders  #编码器
from email.mime.application import MIMEApplication  #主要类型的MIME消息对象应用
from email.mime.base import MIMEBase

# 发件人地址,通过控制台创建的发件人地址
username = '[email protected]'
# 发件人密码,通过控制台创建的发件人密码
password = '*****'
# 自定义的回复地址
replyto = '[email protected]'
# 收件人地址或是地址列表,支持多个收件人,最多30个
rcptto = ['***', '***']

#构建信件标头结构
msg = MIMEMultipart('alternative')  #创建一个多部分的邮件对象
msg['Subject'] = Header('自定义信件主题', 'utf-8')
msg['From'] = formataddr([Header('自定义发信昵称','utf-8'),username])
msg['To'] = formataddr([Header('自定义收信昵称','utf-8'),rcptto])
msg['Reply-to'] = replyto
msg['Message-id'] = make_msgid() #Message-ID标头
msg['Date'] = formatdate()  #日期


#构建文本邮件内容
msg_text = MIMEText('自定义TEXT纯文本部分','plain','utf-8')
msg.attach(msg_text)
#读取文件创建邮件内容
with open('textfile','rb') as fp:   #读取文件内容
    msg_text=MIMEText(fp.read(),'plain','utf-8')

#构建HTML格式的邮件内容
msg_html = MIMEText("

HTML格式邮件

"
,"html","utf-8") msg.attach(msg_html) #构建HTML格式邮件带图片内容 html1 = "
"
msg_html_img = MIMEText(html1,'html','utf-8') msg.attach(msg_html_img) with open("imgfile","rb") as f: msg_img = MIMEImage(f.read()) msg_img.add_header('Content-ID','imgid') #扩展图片标题 msg.attach(msg_img) #带附件的邮件MIMEApplication filename = '简历.pdf' with open(filename,'rb') as f: attachfile = MIMEApplication(f.read()) attachfile.add_header('Content-Disposition', 'attachment', filename=filename) msg.attach(attachfile) #带多个附件的邮件MIMEApplication filenames = ['简历.pdf','副本.pdf'] for tmp in filename: with open(tmp,'rb') as f: attachfiles = MIMEApplication(f.read()) attachfiles.add_header('Content-Disposition', 'attachment', filename=tmp) msg.attach(attachfiles) #带附件的邮件MIMEBase filename1 = '图片.pdf' attachfile_base = MIMEBase('application', 'octet-stream') #创建基础对象指定类型 attachfile_base.set_payload(open(filename,'rb').read()) #设置我有效负载 attachfile_base.add_header('Content-Disposition', 'attachment', filename=('utf-8', '', filename1) ) encoders.encode_base64(attachfile_base) msg.attach(attachfile_base) #创建音频文件 AUDIO_HTML = '''

this's audio file

'''
msg_test1 = MIMEText(AUDIO_HTML,'html','utf-8') msg_audio = MIMEAudio(open('iphone.mp3','rb').read(),'plain') msg_audio.add_header('Content-ID','audioid') msg.attach(msg_test1) msg.attach(msg_audio) #收到邮件不能播放,有待解决! # 发送邮件 try: client = smtplib.SMTP() #需要使用SSL,可以这样创建client #client = smtplib.SMTP_SSL() client.connect('smtp.163.com', 25) #开启DEBUG模式 client.set_debuglevel(1) client.login(username, password) client.sendmail(username, rcptto, msg.as_string()) client.quit() print('email send success!') except smtplib.SMTPConnectError as e: print('邮件发送失败,连接失败:', e.smtp_code, e.smtp_error) except smtplib.SMTPAuthenticationError as e: print('邮件发送失败,认证错误:', e.smtp_code, e.smtp_error) except smtplib.SMTPSenderRefused as e: print('邮件发送失败,发件人被拒绝:', e.smtp_code, e.smtp_error) except smtplib.SMTPRecipientsRefused as e: print('邮件发送失败,收件人被拒绝:', e.smtp_code, e.smtp_error) except smtplib.SMTPDataError as e: print('邮件发送失败,数据接收拒绝:', e.smtp_code, e.smtp_error) except smtplib.SMTPException as e: print('邮件发送失败, ', e.message) except Exception as e: print('邮件发送异常, ', str(e))

四、带有类的邮件发送

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders

class mailsender(object):
    _from = None
    _attachments = []

    def __init__(self,host,port):
        self.smtp = smtplib.SMTP()
        self.smtp_ssl = smtplib.SMTP_SSL()
        self.smtp.connect(host,port)

    def login(self, user, pwd):
        self._from = user
        print("login ...")
        self.smtp.login(user, pwd)

    def add_attachment(self, filename): #添加附加
        att = MIMEBase('application', 'octet-stream')
        att.set_payload(open(filename,'rb').read())
        att.add_header('Content-Disposition', 'attachment', filename = ('utf-8','',filename))
        encoders.encode_base64(att)
        self._attachments.append(att)

    def send(self, subject, content, to_addr):
        msg = MIMEMultipart('alternative')
        contents = MIMEText(content, 'plain', _charset ='utf-8')
        msg['subject'] = subject
        msg['from'] = self._from
        msg['to'] = to_addr
        for att in self._attachments:
            msg.attach(att)
        msg.attach(contents)
        try:
            self.smtp.sendmail(self._from, to_addr, msg.as_string())
            self.smtp.quit()
            print('邮件发送成功!')
        except Exception as e:
            print(str(e))

if __name__ == '__main__':
    emailtext,to_email = input('邮件消息:').split()
    email = mailsender('smtp.163.com','25')
    email.login('[email protected]','xxxxx')
    email.add_attachment('2.png')
    email.send('hello test',emailtext,to_email)

你可能感兴趣的:(python stmp 定时发送邮件)