一、定时发送
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)