一个基与邮件的数据下载存储系统,它包括数据生成和传递以及定时执行两部分。
1、获取特定时间段的数据
2、将获取数据保存到feather/csv
3、邮件发送
4、本地邮件下载,不用登录客户端。下载后改邮件状态为已读。
5、上传网盘
import os
import email
import imaplib
import smtplib
from email.message import EmailMessage
from pandasrw import load,dump
import schedule
import time
##函数########################
# 发送带附件的邮件。参数为发送方用户名、发送方密码、接受方邮箱地址(可以为列表,元素为邮箱地址)、邮件主题、邮件正文,附件路径
def send_attachment(username, password, email_receiver, subject, body, file_path,host, port):
# 创建邮件对象
em = EmailMessage()
em['From'] = username
em['To'] = email_receiver
em['Subject'] = subject
em.set_content(body)
# 打开附件
with open(file_path, 'rb') as f:
file_data = f.read()
file_name = f.name
file_name = os.path.basename(file_name)
# 将附件写入邮件
em.add_attachment(file_data, maintype='application', subtype='octet-stream', filename=file_name)
# 输入stmp的host和port并发送邮件
with smtplib.SMTP_SSL(host, port) as smtp:
smtp.login(username, password)
smtp.send_message(em)
#接收邮件,并下载附件。参数为用户名、密码、下载路径和接受协议配置
def receive_attachment(username, password, download_path, imap_server):
# 建立接受邮件对象
imap = imaplib.IMAP4_SSL(imap_server)
imap.login(username, password)
# 选择收件箱
imap.select('INBOX')
# 接受所有未读邮件,参数'UNSEEN'控制
status, data = imap.search(None, 'UNSEEN')
unread_msg_nums = data[0].split()
# 使用imap.fetch获取邮件内容,然后用email模块的message_from_bytes解析邮件,
# 遍历邮件中的每个部分,看是否有filename字段,如果有就表示这是一个附件,然后获取附件内容并写入文件。
for num in unread_msg_nums:
# RFC822 代表接受邮件的全部内容,包括标题、正文和附件
status, data = imap.fetch(num, '(RFC822)')
msg = email.message_from_bytes(data[0][1])
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
if bool(filename):
print('Downloading attachment:', filename)
attach_data = part.get_payload(decode=True)
# 注意:文件用双反斜杠链接
file_path = download_path + '\\' + filename
with open(file_path, 'wb') as f:
f.write(part.get_payload(decode=True)) # 将附件解码并写入文件
imap.close()
imap.logout()
#改变邮件状态为已读,参数为参数为用户名、密码、接受协议配置
def change_flags(username,password,imap_server):
imap = imaplib.IMAP4_SSL(imap_server)
imap.login(username, password)
imap.select('INBOX')
status, data = imap.search(None, 'UNSEEN')
unread_msg_nums = data[0].split()
for num in unread_msg_nums:
# 修改邮件的标志位为已读
imap.store(num, '+FLAGS', '\\Seen')
imap.close()
imap.logout()
#下载附件并将邮件标记未已读
def receive_attachment_readed(username, password, download_path, imap_server):
# 建立接受邮件对象
imap = imaplib.IMAP4_SSL(imap_server)
imap.login(username, password)
# 选择收件箱
imap.select('INBOX')
# 接受所有未读邮件,参数'UNSEEN'控制
status, data = imap.search(None, 'UNSEEN')
unread_msg_nums = data[0].split()
# 使用imap.fetch获取邮件内容,然后用email模块的message_from_bytes解析邮件,
# 遍历邮件中的每个部分,看是否有filename字段,如果有就表示这是一个附件,然后获取附件内容并写入文件。
for num in unread_msg_nums:
# RFC822 代表接受邮件的全部内容,包括标题、正文和附件
status, data = imap.fetch(num, '(RFC822)')
msg = email.message_from_bytes(data[0][1])
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
if bool(filename):
print('Downloading attachment:', filename)
attach_data = part.get_payload(decode=True)
# 注意:文件用双反斜杠链接
file_path = download_path + '\\' + filename
with open(file_path, 'wb') as f:
f.write(part.get_payload(decode=True)) # 将附件解码并写入文件
# 修改邮件的标志位为已读
imap.store(num, '+FLAGS', '\\Seen')
imap.close()
imap.logout()
通过schedule库来进行定时执行。
def job():
print("我正在执行任务!")
# 设定每天早上8点执行任务
schedule.every().day.at("08:00").do(job)
while True:
try:
schedule.run_pending() # 运行所有可以运行的任务
time.sleep(1)
except Exception as e:
time.sleep(1)
print(e)
1、定点执行下载数据
def job():
host, port = "smtp.qq.com", 465
imap_server = 'imap.qq.com'
username = "xx"
password = "xx"
# 接受方信息,可以是列表[邮箱1,邮箱2]
email_receiver = "xx"
subject = "测试"
body = '邮件正文'
# 要下载的附件文件夹
download_path = "D:\\data\\xx"
#1、在服务器上获取数据,并形成带时间戳的文件
path1=r"xx"
df=load(path1)
path2=r"xx"
fp=dump(df,path2,time=True)
file_path = fp.replace('\\', '\\')
#2、在服务器上发送邮件
send_attachment(username, password, email_receiver, subject, body,file_path,host, port)
time.sleep(10)
os.remove(file_path)
schedule.every(10).seconds.do(job)
while True:
try:
schedule.run_pending() # 运行所有可以运行的任务
time.sleep(1)
except Exception as e:
time.sleep(1)
print(e)
注意:在PyCharm中使用schedule库后,关闭PyCharm并不会停止程序的运行。这是因为schedule库是一个独立的任务调度工具,它会在后台继续运行预定的任务。