一、前言

        今天在自己购买的服务器宝塔面板上折腾了一下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的图标.

python 远程执行windows上的bat文件_压缩文件

 

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的美化版,一样原理,

首先我们利用系统的搜索【任务计划程序】-右键以管理员身份运行,如果登录了微软账号直接点击运行即可

python 远程执行windows上的bat文件_服务器_02

 创建基本任务

python 远程执行windows上的bat文件_上传_03

 填写基本信息

python 远程执行windows上的bat文件_压缩文件_04

 这里看自己需求,创建定时器(触发器)

python 远程执行windows上的bat文件_上传_05

 

python 远程执行windows上的bat文件_服务器_06

 选择启动程序

python 远程执行windows上的bat文件_服务器_07

 选择启动程序以及环境

python 远程执行windows上的bat文件_服务器_08

 

python 远程执行windows上的bat文件_压缩文件_09

 最后点击完成就部署成功了,按照之前设置的触发器定时启动程序了!

第一次写文,有点水,大佬勿锤!!!