【问题标题】:Downloading the most recent file from FTP with Python使用 Python 从 FTP 下载最新文件
【发布时间】:2017-01-14 10:40:29
【问题描述】:

我一直在尝试用 Python 编写一个函数,允许下载最近添加的文件(通过文件名中的时间戳)。

你可以看到格式有一个很大的时间戳。

到目前为止,我在论坛的帮助下得到了以下代码。 在以下代码中,我尝试使用日期字段(实际添加到 FTP 服务器的日期)进行排序。然而, 我想调整这段代码,以便我可以按文件名中的时间戳对文件进行排序。

EDIT(尝试清理一下代码):

def DownloadFileFromFTPServer2 (server, username, password, directory_to_file, file_to_write):
    try:
        f = ftplib.FTP(server)
    except ((socket.error, socket.gaierror), e):
        print ('cannot reach to %s' % server)
        return
    print ("Connected to FTP server")

    try:
        f.login(username, password)
    except ftplib.error_perm:
        print ("cannot login anonymously")
        f.quit()
        return
    print ("Logged on to the FTP server")
    try:
        f.cwd(directory_to_file)
        print ("Directory has been set")
    except Exception as inst:
        print (inst)

    data = []
    f.dir(data.append)
    datelist = []
    filelist =[]

    for line in data:
        print (line)
        col = line.split()
        datestr = ' '.join(line.split()[5:8])
        date = time.strptime (datestr, '%b %d %H:%M')
        datelist.append(date)
        filelist.append(col[8])

    combo = zip (datelist, filelist)
    who = dict ( combo )

    # Sort by dates and get the latest file by date....
    for key in sorted(iter(who.keys()), reverse = True):  
        filename = who[key]

        print ("File to download is %s" % filename)
        try:
            f.retrbinary('RETR %s' % filename, open(filename, 'wb').write)
        except (ftplib.err_perm):
            print ("Error: cannot read file %s" % filename)
            os.unlink(filename)
        else:
            print ("***Downloaded*** %s " % filename)
            print ("Retrieving FTP server data ......... DONE")

        #VERY IMPORTANT RETURN
        return


    f.quit()

    return 1

非常感谢任何帮助。谢谢。

编辑 [已解决]:

线

        date = time.strptime (datestr, '%b %d %H:%M')

应替换为:

        try:
            date = datetime.datetime.strptime (str(col[8]), 'S01375T-%Y-%m-%d-%H-%M-%S.csv')
        except Exception as inst:
            continue     

try-continue 很重要,因为前两条路径行,例如 '.'和 '..' 将导致 ValuError。

【问题讨论】:

  • 我们不需要所有的 FTP 代码。 minimal reproducible example 将包括输入列表和预期结果(输出列表/项目)。剩下的只是污染。
  • 我同意。对不起,混乱。会尝试清理它
  • 如果所有文件都以S01375T- 开头,然后获取全名并对其进行排序——它们应该按照您的预期排序。如果它们以不同的文本开头但长度为 sam,则使用切片 "S01375T-2016-12-01-10-59-03.csv"[8:-4] -> "2016-12-01-10-59-03" 并对这些字符串进行排序,它们应该按照您的预期排序。
  • 如果名称以不同长度的文本开头,但首先 - 总是在年份之前,然后使用 split('-',1) - "S01375T-2016-12-01-10-59-03.csv".split('-', 1)[1] -> '2016-12-01-10-59-03.csv' 并对这些字符串进行排序

标签: python python-3.x sorting urllib ftplib


【解决方案1】:

获得文件名列表后,您可以简单地按文件名排序,因为命名约定是 S01375T-YYYY-MM-DD-hh-mm.csv 这自然会按日期/时间顺序排序。请注意,如果S01375T- 部分不同,您可以在固定位置或第一个- 拆分名称进行排序。

如果不是这种情况,您可以使用datetime.datetime.strptime 方法将文件名解析为datetime 实例。

当然,如果您想真正简化事情,您可以使用PyFileSystem FTPFS,它有多种方法可以让您将 FTP 系统视为一个缓慢的本地文件系统。

【讨论】:

  • 您好,我的文件名为 col[8]。应用 date = time.strptime (str(col[8]), 'S01375T-%Y-%m-%d-%H-%M-%S.csv') 导致错误:ValueError: time data '。 '与格式“S01375T-%Y-%m-%d-%H-%M-%S.csv”不匹配
  • 你需要 datetime.datetime.strptime。如果这不起作用,请尝试 str(col[8])[8:-4], '%04Y-%02m-%02d-%02H-%2M-%02S'))
  • 已解决。谢谢巴恩斯先生,任何有同样问题的人都应该检查我的编辑。
【解决方案2】:

尝试使用 ftp.dir 中的-t 选项,这将按日期倒序排列,然后取列表中的第一个:

data = []
ftp.dir('-t',data.append)
filename = data[0]

【讨论】:

    【解决方案3】:

    您需要正确地从文件名中提取时间戳。 您可以在第一个“-”处拆分文件名并删除文件扩展名“.csv”(f.split('-', 1)[1][:-4])。
    然后你只需要构造日期时间对象进行排序。

    from datetime import datetime
    
    def sortByTimeStampInFile(fList):
        fileDict = {datetime.strptime(f.split('-', 1)[1][:-4], '%Y-%m-%d-%H-%M-%S'): f for f in fList if f.endswith('.csv')}
        return [fileDict[k] for k in sorted(fileDict.keys())]
    
    
    files = ['S01375T-2016-03-01-12-00-00.csv', 'S01375T-2016-01-01-13-00-00.csv', 'S01375T-2016-04-01-13-01-00.csv']
    print(sortByTimeStampInFile(files))
    

    返回:

    ['S01375T-2016-01-01-13-00-00.csv', 'S01375T-2016-03-01-12-00-00.csv', 'S01375T-2016-04-01-13-01-00.csv']
    

    顺便说一句。只要你的时间格式是“年-月-日-时-分-秒”,一个简单的字符串排序就可以了:

    sorted([f.split('-', 1)[1][:-4] for f in fList if f.endswith('.csv')])
    >>> ['2016-01-01-13-00-00', '2016-03-01-12-00-00', '2016-04-01-13-01-00']
    

    【讨论】:

      猜你喜欢
      • 2017-04-12
      • 1970-01-01
      • 2014-04-09
      • 1970-01-01
      • 2015-07-27
      • 2021-10-10
      相关资源
      最近更新 更多