用python定时发送邮件

用python定时发送邮件用 python 定时发送邮件 2020 12 24Python3 6 3 Anacondacust 64 bit 关键词 python 邮件发送 定时一 用 python 实现邮件发送 一 用到的模块 emailType moduleString module email from D Anaconda lib email init py File d anaconda lib email i module email from D Anaconda lib email init py

python定时发送邮件

关键词:python邮件发送;定时

一、 用python实现邮件发送

Python对SMTP的支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件

电子邮件消息由headers(标题)和payloads(有效负载, 也称为content)组成。headers是RFC 5322或RFC 532风格的字段名和值,字段名和值用冒号分隔。冒号既不是字段名的一部分也不是字段值的一部分。payloads可以是一个简单的文本消息,或者一个二进制对象,或者一个结构化的子消息序列,每个子消息都有自己的头部集和有效负载。后一种类型的payloads由MIME类型的消息来指示,例如multipart/或message/rfc822*。
——19.1.1. email.message: Representing an email message

(一)用到的模块

【1. email

(1) email.mime: Python文档中对mime的介绍

email.mime.text.MIMEText(_text, _subtype=‘plain’, _charset=None, *, policy=compat32)

MIMEText用来生成一个主要类型为text的MIME对象。

(2) email.utils.parseaddr(address)email.utils.formataddr((name_encoded_by_Header, address))

写邮件的时候,Email的地址可以有两种写法。一种写法是:,另一种写法是:name

。用前者写法,在邮箱中就会显示为xxx

;用后者,就会显示为name

,更为清晰、专业。 【
有的时候,用前者写法也会显示name,是因为对方邮箱中保存了这个地址,类似于对方手机中保存了手机号和姓名。】而
parseaddr函数就是将str “name

”转换成一个tuple。



In[48]: a = parseaddr('name 
   
     ' 
   ) In[49]: a Out[49]: ('name', '') In[50]: type(a) Out[50]: tuple In[53]: name, addr = parseaddr('boy 
   
     ' 
   ) In[54]: name Out[54]: 'boy' In[55]: addr Out[55]: '' 

解析出name和address后,需要用formataddr()函数将其变为标准的email地址。

标准的email地址格式为’name

’,因此formataddr()与parseaddr()相反,会将tuple转换成str。

注意:formataddr()接收的name需要经Header()进行编码处理后才行。【注1】

from email.header import Header In[67]: name, addr = parseaddr('boy 
   
     ' 
   ) In[68]: a = formataddr((name, addr)) # 将name直接传入 In[69]: b = formataddr((Header(name, 'utf-8').encode(), addr)) # 将name用Header()编码处理后传入 In[70]: a Out[70]: 'boy 
   
     ' 
    In[71]: b Out[71]: '=?utf-8?q?boy?= 
   
     ' 
    #下文msg[’From‘]和msg['To']只识别这种格式  

构建邮件正文:

from email.mime.text import MIMEText from email.header import Header from email.utils import parseaddr, formataddr # 编写一个进行地址解析、生成标准地址格式的函数 def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr)) # 设置邮件内容 msg = MIMEText('This is an email for testing.', 'plain', 'utf-8') # 设置邮件收发件人名称、主题等 ''' 收发件人名称、主题,不是通过SMTP发送给MTA的,而是包含在发送给MTA的文本中(msg)。 ''' msg['From'] = _format_addr('发件人名 <%s>' % '发件人邮箱') msg['To'] = _format_addr('收件人名 <%s>' % '收件人邮箱') #msg['From']和msg['To']直接使用formataddr后的字符串,如果有多个这样的字符串地址,用逗号(,)分开。 msg['Subject'] = Header('TEST', 'utf-8').encode() # 此处,主题也经过了Header的编码处理 

【2. smtplib】

在使用email构建好邮件正文后,用smtplib来发送邮件。

smtplib.SMTP()函数,设置服务器地址和端口号

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

设置发送参数:

from_addr = '' password = 'GJZDZMUF' # 密码或邮箱授权码 to_addr = '' smtp_server = 'smtp.126.com' server = smtplib.SMTP(smtp_server, 25) # 设置服务器和端口号 server.set_debuglevel(1) # 打印出和SMTP服务器交互的所有信息,如果没有这一语句,将不打印任何信息 server.login(from_addr, password) # 进行登录 server.sendmail(from_addr, [to_addr], msg.as_string()) # 1. msg.as_string()把MIMEText对象变成str(包含utf-8编码信息和Base64编码) # 2. [to_addr]表示可以有多个收件人。多个收件人,传入list。当然,也可以在前面to_addr处直接用list进行赋值,那么此处就不是传入[to_addr],而是传入to_addr了 server.quit() 

二、定时

【方法一】利用datetime包

datetime.datetime.now()可以返回现在的本地时间(默认本地时区)

In[7]: import datetime In[8]: now = datetime.datetime.now() # 返回datetime.datetime数据类型 In[9]: print(now) 2020-12-30 17:03:09. In[10]: now.replace(microsecond = 0) # 通过replace()方法去掉微秒 Out[10]: datetime.datetime(2020, 12, 30, 17, 3, 9) In[11]: print(now) # replace()方法不改变now本身 2020-12-30 17:03:09. In[12]: print(now.replace(microsecond = 0)) 2020-12-30 17:03:09 

设定定时变量scheduled_time,并判断是否达到该时间:

scheduled_time = datetime.datetime(2021, 1, 1, 00, 00, 00) # 将时间定为2021年1月1月0时0分0秒 while True: now = datetime.datetime.now().replace(microsecond=0) if now == scheduled_time: print('时间到啦!新年快乐!') break # 不写break的话,也可以增加scheduled_time的值。如果都不写,会遇到重复运行的问题 

三、写一个完整的程序

from email import encoders from email.header import Header from email.mime.text import MIMEText from email.utils import parseaddr, formataddr import smtplib def _format_addr(s): name, addr = parseaddr(s) return formataddr((Header(name, 'utf-8').encode(), addr)) from_addr = '' password = 'GJZDZMUF' # 密码或邮箱授权码 to_addr = '' smtp_server = 'smtp.126.com' def send_mail(): server = smtplib.SMTP(smtp_server, 25) # server.set_debuglevel(1) server.login(from_addr, password) server.sendmail(from_addr, [to_addr], msg.as_string()) server.quit() import datetime i = 1 limit = 3 scheduled_time = datetime.datetime(2020, 12, 30, 18, 0, 0) print('首次发送邮件的时间是:', scheduled_time) while True: now = datetime.datetime.now().replace(microsecond=0) if now == scheduled_time: msg = MIMEText('This is a test' , 'plain', 'utf-8') msg['From'] = _format_addr('发件人 <%s>' % from_addr) msg['To'] = _format_addr('收件人 <%s>' % to_addr) msg['Subject'] = Header('TEST%s...' % i, 'utf-8').encode() send_mail() scheduled_time = scheduled_time + datetime.timedelta(seconds = 10) print('第%s次邮件发送成功!现在时间是' % i, datetime.datetime.now().replace(microsecond=0)) i = i + 1 if i < limit: print('下一次发送邮件的时间是:', scheduled_time.replace(microsecond=0)) else: pass if i >= limit: print('所有邮件发送完毕,现在的时间是:', datetime.datetime.now().replace(microsecond=0)) break 

四、遇到的错误

【注1】实际操作时,如果传入未被Header编码处理的name,发送邮件时暂未发现报错(英文与中文皆是)。因此此处待进一步验证。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/210844.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午11:47
下一篇 2026年3月18日 下午11:47


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号