首页 > 技术文章 > Python 自动发送文件到邮箱

wujbclzw 2017-11-21 14:48 原文

在服务器上搭建了一个小应用,为保证数据安全,每天晚上做一次备份,备份文件为.bak后缀。目前备份文件经过压缩后,大小约20M,可以通过网易的邮箱发送。

要点:

  1. 使用7z压缩数据文件

    Python调用7z压缩文件的方法是调用 os.command()函数,但事先要将 7z.exe的路径加入环境变量。(这里用的windows系统测试)

    7z的压缩命令:

    7z a filename.7z file_to_be_compressed

  2. 网易邮箱登陆,通过Python登陆邮箱发送邮件,需要开通邮箱的POP3服务。现在申请的163邮箱,开通POP3服务时,需要开通授权码。Python程序中使用授权码登陆邮箱。以前申请的163邮箱如果开通了POP3服务则可使用密码登陆。

代码如下:

 # coding:utf-8

 

'''

backup files automation

put the .bak files in 'backup' folder

the python script will compress them and send by email

 

running condition :

1. Python

2. 7-zip and set the 7z environment path

 

'''

 

import smtplib

import os, glob

import datetime

from time import sleep

from email import encoders

from email.header import Header

from email.mime.text import MIMEText

from email.utils import parseaddr, formataddr

from email.mime.multipart import MIMEMultipart

from email.mime.base import MIMEBase

 

 

def _format_addr(s):

name, addr = parseaddr(s)

return formataddr((Header(name, 'utf-8').encode(), addr))

 

 

def send_email(attach_file):

# 输入Email地址和口令:

# 1442464708 Sendemailbypython

from_addr = 's******n@163.com'

# 授权码

password = 'V*************'

# 输入收件人地址:

to_addr = 'wujbclzw@163.com'

# 输入SMTP服务器地址:

smtp_server = 'smtp.163.com'

 

# msg = "test for send email"

 

date_str = datetime.date.today().strftime("%Y-%m-%d")

email_title = "%s数据库备份" % date_str

 

msg = MIMEMultipart()

msg['From'] = _format_addr('文件备份 <%s>' % from_addr)

msg['To'] = _format_addr('数据库备份 <%s>' % to_addr)

msg['Subject'] = Header(email_title, 'utf-8').encode()

 

# 邮件正文是MIMEText:

msg.attach(MIMEText('数据库备份文件', 'plain', 'utf-8'))

 

# 添加附件就是加上一个MIMEBase,从本地读取一个图片:

with open(attach_file, 'rb') as f:

# 设置附件的MIME和文件名,这里是png类型:

file_name = os.path.basename(attach_file)

mime = MIMEBase('Compact File', 'rar', filename=file_name)

# 加上必要的头信息:

mime.add_header('Content-Disposition', 'attachment', filename=file_name)

mime.add_header('Content-ID', '<0>')

mime.add_header('X-Attachment-Id', '0')

# 把附件的内容读进来:

mime.set_payload(f.read())

# Base64编码:

encoders.encode_base64(mime)

# 添加到MIMEMultipart:

msg.attach(mime)

 

server = smtplib.SMTP(smtp_server, 25) # SMTP协议默认端口是25

# server.set_debuglevel(1)

server.login(from_addr, password)    # 使用授权码登陆,不是邮箱的密码

server.sendmail(from_addr, [to_addr], msg.as_string())

server.quit()

 

 

def Compact_file():

'''

压缩并发送邮件

:return:

'''

direct_dir = "backup\\"

fs = glob.glob(direct_dir + "*.BAK")

 

for fItem in fs:

fbase = os.path.basename(fItem)

file_7z = "%s%s.7z" % (direct_dir, fbase)

# if .7z file is exist, remove it

if os.path.exists(file_7z):

os.remove(file_7z)

# Compress source file

cmd = "7z a %s %s" % (file_7z, fItem)

os.system(cmd)

 

# send by email

send_email(attach_file=file_7z)

# remove source file

if os.path.exists(file_7z):

os.remove(file_7z)

if os.path.exists(fItem):

os.remove(fItem)

print('Compress %s and send by email.' % fItem)

 

 

if __name__ == "__main__":

while True:

# run send mail at 02:00:00 ereryday

nt = datetime.datetime.now()

if nt.hour >= 1:

next_day = nt + datetime.timedelta(1)

else:

next_day = nt

run_time = datetime.datetime(next_day.year, next_day.month, next_day.day, 2, 0, 0)

delays = (run_time - nt).seconds

print("now time : %s" % nt.strftime('%Y-%m-%d %H:%M:%S'))

# print(run_time.strftime('%Y-%m-%d %H:%M:%S'))

print("wait for %s senconds." % delays)

# sleep(10)

sleep(delays)

nt = datetime.datetime.now()

print("now time : %s" % nt.strftime('%Y-%m-%d %H:%M:%S'))

print("Srart to compress file and send mail.")

Compact_file()

 

参考资料:

https://jingyan.baidu.com/article/d8072ac498792dec95cefd81.html

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432005226355aadb8d4b2f3f42f6b1d6f2c5bd8d5263000

推荐阅读