簡體   English   中英

Python FTP按日期獲取最新文件

[英]Python FTP get the most recent file by date

我正在使用 ftplib 連接到 ftp 站點。 我想獲取最近上傳的文件並下載它。 我能夠連接到 ftp 服務器並列出文件,我也將它們放在一個列表中並轉換了datefield 是否有任何功能/模塊可以獲取最近的日期並從列表中輸出整行?

#!/usr/bin/env python

import ftplib
import os
import socket
import sys


HOST = 'test'


def main():
    try:
        f = ftplib.FTP(HOST)
    except (socket.error, socket.gaierror), e:
        print 'cannot reach to %s' % HOST
        return
    print "Connect to ftp server"

    try:
        f.login('anonymous','al@ge.com')
    except ftplib.error_perm:
        print 'cannot login anonymously'
        f.quit()
        return
    print "logged on to the ftp server"

    data = []
    f.dir(data.append)
    for line in data:
        datestr = ' '.join(line.split()[0:2])
        orig-date = time.strptime(datestr, '%d-%m-%y %H:%M%p')


    f.quit()
    return


if __name__ == '__main__':
    main()

解決:

data = []
f.dir(data.append)
datelist = []
filelist = []
for line in data:
    col = line.split()
    datestr = ' '.join(line.split()[0:2])
    date = time.strptime(datestr, '%m-%d-%y %H:%M%p')
    datelist.append(date)
    filelist.append(col[3])

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

for key in sorted(who.iterkeys(), reverse=True):
   print "%s: %s" % (key,who[key])
   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
   return

f.quit()
return

一個問題,是否可以從字典中檢索第一個元素? 我在這里所做的是 for 循環只運行一次並退出,從而為我提供第一個排序的值,這很好,但我認為以這種方式執行它不是一個好習慣..

對於那些正在尋找在文件夾中查找最新文件的完整解決方案的人:

MLSD

如果您的 FTP 服務器支持MLSD命令,則解決方案很簡單:

entries = list(ftp.mlsd())
entries.sort(key = lambda entry: entry[1]['modify'], reverse = True)
latest_name = entries[0][0]
print(latest_name)

列表

如果您需要依賴過時的LIST命令,則必須解析它返回的專有列表。

常見的 *nix 列表如下:

-rw-r--r-- 1 user group           4467 Mar 27  2018 file1.zip
-rw-r--r-- 1 user group         124529 Jun 18 15:31 file2.zip

有了這樣的清單,此代碼將執行以下操作:

from dateutil import parser

# ...

lines = []
ftp.dir("", lines.append)

latest_time = None
latest_name = None

for line in lines:
    tokens = line.split(maxsplit = 9)
    time_str = tokens[5] + " " + tokens[6] + " " + tokens[7]
    time = parser.parse(time_str)
    if (latest_time is None) or (time > latest_time):
        latest_name = tokens[8]
        latest_time = time

print(latest_name)

這是一種相當脆弱的方法。


MDTM

一種更可靠但效率較低的方法是使用MDTM命令來檢索單個文件/文件夾的時間戳:

names = ftp.nlst()

latest_time = None
latest_name = None

for name in names:
    time = ftp.voidcmd("MDTM " + name)
    if (latest_time is None) or (time > latest_time):
        latest_name = name
        latest_time = time

print(latest_name)

有關代碼的替代版本,請參閱@Paulo 的答案


非標准 -t 開關

某些 FTP 服務器支持用於NLST (或LIST )命令的專有非標准-t開關。

lines = ftp.nlst("-t")

latest_name = lines[-1]

請參閱如何獲取按修改時間排序的 FTP 文件夾中的文件


下載找到的文件

無論您使用什么方法,一旦您擁有latest_name ,您就可以將其作為任何其他文件下載:

file = open(latest_name, 'wb')
ftp.retrbinary('RETR '+ latest_name, file.write)

也可以看看

為什么不使用 next dir 選項?

ftp.dir('-t',data.append)

使用此選項,文件列表按時間順序從最新到最舊。 然后只需檢索列表中的第一個文件即可下載。

使用NLST ,如 Martin Prikryl 的響應所示,您應該使用sorted方法:

ftp = FTP(host="127.0.0.1", user="u",passwd="p")
ftp.cwd("/data")
file_name = sorted(ftp.nlst(), key=lambda x: ftp.voidcmd(f"MDTM {x}"))[-1]

我不知道你的 ftp 怎么樣,但你的例子對我不起作用。 我更改了與日期排序部分相關的一些行:

    import sys
    from ftplib import FTP
    import os
    import socket
    import time

    # Connects to the ftp
    ftp = FTP(ftpHost)
    ftp.login(yourUserName,yourPassword)
    data = []
    datelist = []
    filelist = []
    ftp.dir(data.append)
    for line in data:
      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)
    for key in sorted(who.iterkeys(), reverse=True):
      print "%s: %s" % (key,who[key])
      filename = who[key]
      print "file to download is %s" % filename
      try:
        ftp.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
    ftp.quit()

如果您在time.struct_time擁有time.struct_time所有日期( strptime會給您這個),那么您所要做的就是sort列表進行sort

這是一個例子:

#!/usr/bin/python

import time

dates = [
    "Jan 16 18:35 2012",
    "Aug 16 21:14 2012",
    "Dec 05 22:27 2012",
    "Jan 22 19:42 2012",
    "Jan 24 00:49 2012",
    "Dec 15 22:41 2012",
    "Dec 13 01:41 2012",
    "Dec 24 01:23 2012",
    "Jan 21 00:35 2012",
    "Jan 16 18:35 2012",
]

def main():
    datelist = []
    for date in dates:
        date = time.strptime(date, '%b %d %H:%M %Y')
        datelist.append(date)

    print datelist
    datelist.sort()
    print datelist

if __name__ == '__main__':
    main()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM