ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python从ftp抓取最近三天数据

2022-05-17 20:01:35  阅读:148  来源: 互联网

标签:ftp 文件 python 抓取 time print local dir


https://blog.csdn.net/weixin_42496466/article/details/120293070?spm=1001.2014.3001.5502、
不啰嗦,直接上代码:

import ftplib
import os
import socket
import sys
import time

HOST = '**' # ftp地址
USER = '**' # 用户名
PASSWD = '**' # 用户密码

LocalDir = r'**' # 本地存贮路径
FTPDir = sys.argv[1] # 需要下载的ftp目录路径
local_fname = 'checkfile.txt' # 用本地存放已下载过的文件名

local_files = [] # 存放从checkfile.txt中读回的文件名
appendFiles = [] # 存放需要写进checkfile.txt的文件各

def FtpConnect(host, username, passwd):
'''
连接并登录ftp服务器

host:ftp地址  
username:用户名  
passwd:用户密码  
'''  
try:  
    ftp = ftplib.FTP(HOST)  
    # ftp.encoding = 'utf-8' #解决中文乱码问题  
    # ftp.set\_debuglevel(0)  #不开启调试模式  
except (socket.error, socket.gaierror):  
    print('Error, cannot reach ' + HOST)  
    return None  
else:  
    print('Connect To Host Success...')

try:  
    ftp.login(USER, PASSWD)  
except ftplib.error\_perm:  
    print('Username or Passwd Error')  
    # ftp.quit()  
    return None  
else:  
    print(ftp.getwelcome())  # 显示登录ftp信息  
    print('Login Success...')  
    ftp.dir()  # 显示目录下所有目录信息  
    print("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")  
return ftp

def filelist(ftp):
'''
递归ftp当前目录下的所有文件及目录信息
'''
flist = []
ftp.dir('.', flist.append) # 将目录中的内容存进flist列表
files = [f.split()[-1] for f in flist if f.startswith('-')] # 读取flist列表中的信息,以-开头的是常规文件,将该信息以空字符分割成列表,取最后的元素即为文件名
fids = [f.split(None, 4)[-1] for f in flist if f.startswith('-')] # 读取flist列表中的信息,以-开头的是常规文件,将该信息以前4个空字符分割成列表,
# 最后的元素包括了文件的大小,修改日期时间,可作为文件的标识
dictf = dict(zip(files, fids)) # 将文件名与对应的标识合成字典
dirs = [f.split()[-1] for f in flist if f.startswith('d')] # 读取flist列表中的信息,以d开头的是目录,将该信息以空字符分割成列表,取最后的元素即为目录名
# print(dirs)
return (dictf, dirs)

def FtpDownloadDir(ftp, ftp_dir, local_dir):
'''
递归下载ftp指定目录下的所有文件及目录
'''
print('+++++++++++++++++++++++++++++++++++++++++++++++++++++')
print(f'Walking to {ftp_dir}')
print(f'Walking to {local_dir}')
if ftp_dir == "/":
dirname = "AllDir" # 用于本地创建新目录,如果下载的是FTP根目录,则在目录名为AllDir
else:
dirname = os.path.basename(ftp_dir) # 否则本地目录名与FTP目录名一样

ftp.cwd(ftp\_dir)  # 进入ftp对应目录  
os.chdir(local\_dir)  # 进入本地下载目录

if os.path.exists(dirname):  # 如果本地dirname目录已存在  
    os.chdir(dirname)  # 则直接进入该目录  
else:  
    try:  
        os.mkdir(dirname)  # 否则在本地创建该目录  
    except OSError:  
        print('OSError!')  
    else:  
        os.chdir(dirname)  # 创建完后进入该目录

ftp\_curr\_dir = ftp.pwd()  # 获取FTP当前目录路径  
print(ftp\_curr\_dir)  
local\_curr\_dir = os.getcwd()  # 获取本地当前目录路径  
# print(f'Changing to {ftp\_curr\_dir}')  
# print(f'Changing to {local\_curr\_dir}')

dictf, dirs = filelist(ftp)  # 调用filelist函数,递归ftp当前目录下的所有文件及目录

for f, k in dictf.items():  # 获取到的文件信息的键值对  
    if ".tif" not in f or ".tif" not in k:  
        continue  
    else:  
        if k not in local\_files:  # 文件标识与本地存储的已下载过的文件标识做对比  
            FtpDownloadFile(ftp, f, f)  # k不在local\_files中说明该文件未下载过,则下载该文件  
            appendFiles.append(k)  # 同时将该文件的标识存储到appenFiles列表中,用于下载完成后更新本地的checkfile.txt文件

for d in dirs:  # 对子目录进行处理  
    if isVaildDate(d):  
        if compare\_time(d) + 24\*3600\*3 >= 0:    #抓取最近三天的  
            FtpDownloadDir(ftp, d, local\_curr\_dir)  # 调用自身,递归下载子目录中的文件  
            ftp.cwd('..')  
            os.chdir('..')  # 每次递归完成后,ftp及本地都返回上一层目录,继续其他子目录的处理  
    else:  
        FtpDownloadDir(ftp, d, local\_curr\_dir)  # 调用自身,递归下载子目录中的文件  
        ftp.cwd('..')  
        os.chdir('..')  # 每次递归完成后,ftp及本地都返回上一层目录,继续其他子目录的处理  
os.chdir(local\_dir)

def isVaildDate(date):
try:
if len(date) == 4:
time.strptime(date, "%Y")
return True
if len(date) == 6:
time.strptime(date, "%Y%m")
return True
if len(date) == 8:
time.strptime(date, "%Y%m%d")
return True
return False
except:
return False

def compare_time(time1):
fmt="%Y"
if len(time1) == 6:
fmt="%Y%m"
if len(time1) == 8:
fmt="%Y%m%d"
time2=time.strftime(fmt,time.localtime(time.time()))
s_time = time.mktime(time.strptime(time1,fmt))
e_time = time.mktime(time.strptime(time2,fmt))
return int(s_time) - int(e_time)

def FtpDownloadFile(ftp, remotefile, localfile):
'''
下载ftp当前目录的文件到本地的当前目录中
'''
buffer_size = 10240 # 默认是8192
try:
f = open(localfile, 'wb')
ftp.retrbinary(f'RETR {remotefile}', f.write, buffer_size)
except ftplib.error_perm:
print(f'File:{f} Download Error')
# os.unlink(localpath)
else:
print(f'File:{f} Download Success...')
finally:
f.close()

def operfile(fileTxt, op):
'''
操作下载目录中的文件人工
op为'r'时读取该文件,如文件不存在则忽略
op为'w'时追加写入文件
'''
fp = os.path.join(LocalDir, fileTxt)
if op == 'r':
print(f'从 {fp} 中读取本地文件列表')
try:
with open(fp, 'r')as ft:
for line in ft:
line = line.strip()
local_files.append(line)
except Exception as e:
print(e)
elif op == 'w':
print(f'更新 {fileTxt} 中文件列表')
try:
with open(fp, 'a') as ft:
ft.writelines([f'{x}\n' for x in appendFiles])
except Exception as e:
print(e)
else:
print("参数2请输入'r'或者'w'!")

if __name__ == '__main__':
config = sys.argv[1]
ftp = FtpConnect(HOST, USER, PASSWD) # 连接并登录ftp服务器
ftp.encoding = 'utf-8'
if ftp: # 如果登录成功
operfile(local_fname, 'r') # 从checkfile.txt中获取已下载过的文件
FtpDownloadDir(ftp, FTPDir, LocalDir) # 将ftp指定目录下的文件更新到本地目录中
if appendFiles: # 如果有新文件更新到本地
operfile(local_fname, 'w') # 则将其追加到checkfile.txt中
appendFiles = [] # 清空列表
else:
print(f'无需更新{local_fname}')
ftp.quit()
print("FTP QUIT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")

感谢支持技术分享,请扫码点赞支持:

技术合作交流qq:2401315930

本文转自 https://blog.csdn.net/weixin_42496466/article/details/120293070?spm=1001.2014.3001.5502,如有侵权,请联系删除。

标签:ftp,文件,python,抓取,time,print,local,dir
来源: https://www.cnblogs.com/hustshu/p/16282166.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有