一、前言
今天在自己购买的服务器宝塔面板上折腾了一下FTP,手动开通了FTP功能,然后在电脑本地上传和下载了一些文件,折腾折腾着突然想到一个点子,把我服务器当作一个云盘,电脑编写一个py脚本定时上传自己的一些经常要备份的重要文件,防止文件丢失。这不就白嫖了一个云盘?
于是我就开始在csdn论坛上面搜索看看有没有相似功能的帖子模仿着写一个脚本自己用,结果还真找到一个老哥的帖子【用Python实现定时备份Mongodb数据,并上传到FTP服务器】于是就模仿着写了个脚本。第一次写博客,记录一下。
二、准备工作
1.一台服务器,最近阿里腾讯都有活动,几十块直接买一年,我这买的是阿里的2H2G的.
2.准备好python环境以及IDE工具,我这里用的Python3.9,IDE:Pycharm.
3. 在服务器搭建好FTP服务器,这里我参考【宝塔面板搭建ftp服务器】
三、放出代码(这里模仿上面老哥的写法,先把文件压缩后上传)
首先放出这是后面需要用到的库
import datetime
import os.path
import time
import zipfile
from ftplib import FTP
from win10toast import ToastNotifier
压缩文件夹减小文件内存方便文件上传,(我把老哥的压缩部分代码修改了一下,修复了zipfile压缩的文件路径太深的问题,这部分可以直接复制拿去用)
# 解决zipfile压缩的文件路径太深问题
def get_zip_file(file_path, file_lists):
file_s = os.listdir(file_path)
for file in file_s:
if os.path.isdir(file_path + '/' + file):
get_zip_file(file_path + '/' + file, file_lists)
else:
file_lists.append(file_path + '/' + file)
def zip_Folder(file_path, output_path, date):
"""
:param file_path: 被压缩的源数据位置
:param output_path: 压缩之后文件的存放路径
:param date: 执行压缩的当前时间,datetime产生
:return: 压缩文件的路径
"""
startTime = time.perf_counter()
desName = f"{output_path}Work备份{date.strftime('%Y')}{date.strftime('%m')}{date.strftime('%d')}.zip"
# 检查是否已经压缩过了
if os.path.exists(desName):
print(
f"该文件已经存在,跳过压缩此文件,time:{datetime.datetime.now().strftime('%Y-%d-%m %H:%M:%S')},耗时:{(time.perf_counter() - startTime):.2f}s")
return desName
z = zipfile.ZipFile(desName, 'w', zipfile.ZIP_DEFLATED)
file_lists = []
get_zip_file(file_path, file_lists)
for file in file_lists:
try:
full_file_path = file
compressed_file_path = file.split(file_path)[1]
z.write(full_file_path, compressed_file_path)
except Exception as e:
print(f"except: {e}, 无法压缩文件: {file}")
z.close()
print(
f"压缩完成,time:{datetime.datetime.now().strftime('%Y-%d-%m %H:%M:%S')},耗时:{(time.perf_counter() - startTime):.2f}s")
return desName
FTP上传部分代码
就是抄老哥的,自己加入了Win10通知,上传完成后系统弹出通知起到提醒作用,左上角那个图标可以更换自己喜欢的图标,格式是xx.ico的图标.
def ftp_Upload(filename, folder, ftp_url, ftp_port):
"""
:param filename: 待上传文件路径
:param folder: 文件上传至FTP服务器上的存储目录
:param ftp_url: FTP服务器IP
:param ftp_port: 端口号,默认为21
:return: status code
"""
ftp = FTP()
ftp.set_debuglevel(0) # 设置调试级别,显示详细信息:2,关闭显示:0
ftp.connect(ftp_url, ftp_port)
ftp.login(username, password) # 登录,如果匿名登录则用空串代替
ftp.cwd(folder) # 切换到 FTP 服务器上的目录
bufsize = 1024 # 设置缓冲块大小
file_handler = open(filename, 'rb')
res = -1
try:
res = ftp.storbinary(f"STOR {os.path.basename(filename)}", file_handler, bufsize) # upload file
except Exception as e:
print(f"except: {e}, cannot upload file: {ftp_url}:{ftp_port} {filename}")
finally:
ftp.set_debuglevel(0) # 关闭debug信息
file_handler.close()
ftp.quit()
# 加入Win10通知,上传完成后系统弹出通知起到提醒作用
toaster = ToastNotifier()
toaster.show_toast("文件备份上传完成!",
"您位于{}的文件已经压缩并且备份到服务器了!!!".format(Folder_path),
icon_path = r"D:\Image\icon\imageres\Imageres_dll_141.ico", # 通知图标绝对路径(自己更换喜欢的图标)
duration = 20) # 通知显示时间:秒,我想一直显示通知,奈何这个库不支持
# 等待线程通知完成
while toaster.notification_active():
time.sleep(0.1)
return res
然后把配置信息完善一下(放在主函数前面就好了)
# 定义配置信息
Folder_path = "D:/Desktop/Material" # 被压缩的数据,文件夹形式
ZIP_Folder_path = "D:/Desktop/Backup_Zip/" # 压缩好的数据临时存放的位置
FTP_file_path = "/xx" # 数据在FTP服务器上存放的位置
FTP_url = "**.***.***.***" # FTP服务器地址
FTP_port = 21 # FTP服务端口号,一般默认21
username = '***' # FTP服务器账号 匿名留空
password = '********' # FTP服务器密码 匿名留空
主函数代码
if __name__ == '__main__':
Backup_Time = datetime.datetime.now() # 产生当前执行备份时间,用作备份名字
Zip_file_name = zip_Folder(Folder_path, ZIP_Folder_path, Backup_Time) # 执行压缩文件夹
ftp_Upload(Zip_file_name, FTP_file_path, FTP_url, FTP_port)
脚本运行就会执行压缩【Folder_path】文件夹下文件到【ZIP_Folder_path】路径下,zip格式压缩包,然后上传到远程FTP服务器上
四、配置win10定时任务,定时执行python脚本
我这里用了win11,但众所周知,win11就是win10的美化版,一样原理,
首先我们利用系统的搜索【任务计划程序】-右键以管理员身份运行,如果登录了微软账号直接点击运行即可
创建基本任务
填写基本信息
这里看自己需求,创建定时器(触发器)
选择启动程序
选择启动程序以及环境
最后点击完成就部署成功了,按照之前设置的触发器定时启动程序了!
第一次写文,有点水,大佬勿锤!!!