Python의 ftplib를 사용하여 이식 가능한 디렉토리 목록 가져오기

StackOverflow https://stackoverflow.com/questions/111954

  •  02-07-2019
  •  | 
  •  

문제

Python에서 전체 FTP 지원을 위해 ftplib를 사용할 수 있습니다.그러나 디렉토리 목록을 얻는 가장 좋은 방법은 다음과 같습니다.

# File: ftplib-example-1.py

import ftplib

ftp = ftplib.FTP("www.python.org")
ftp.login("anonymous", "ftplib-example-1")

data = []

ftp.dir(data.append)

ftp.quit()

for line in data:
    print "-", line

결과는 다음과 같습니다.

$ python ftplib-example-1.py
- total 34
- drwxrwxr-x  11 root     4127         512 Sep 14 14:18 .
- drwxrwxr-x  11 root     4127         512 Sep 14 14:18 ..
- drwxrwxr-x   2 root     4127         512 Sep 13 15:18 RCS
- lrwxrwxrwx   1 root     bin           11 Jun 29 14:34 README -> welcome.msg
- drwxr-xr-x   3 root     wheel        512 May 19  1998 bin
- drwxr-sr-x   3 root     1400         512 Jun  9  1997 dev
- drwxrwxr--   2 root     4127         512 Feb  8  1998 dup
- drwxr-xr-x   3 root     wheel        512 May 19  1998 etc
...

나는 결과를 분석하여 디렉토리 목록을 얻는 것이 아이디어라고 생각합니다.그러나 이 목록은 FTP 서버의 목록 형식 지정 방식에 직접적으로 의존합니다.FTP 서버가 이 목록의 형식을 지정할 수 있는 다양한 방법을 모두 예상해야 하는 코드를 작성하는 것은 매우 지저분할 것입니다.

디렉토리 목록으로 배열을 채우는 이식 가능한 방법이 있습니까?

(배열에는 폴더 이름만 있어야 합니다.)

도움이 되었습니까?

해결책

사용해 보세요 ftp.nlst(dir).

그러나 폴더가 비어 있으면 오류가 발생할 수 있습니다.

files = []

try:
    files = ftp.nlst()
except ftplib.error_perm, resp:
    if str(resp) == "550 No files found":
        print "No files in this directory"
    else:
        raise

for f in files:
    print f

다른 팁

FTP 디렉토리 목록을 구문 분석하는 신뢰할 수 있고 표준화된 방법은 MLSD 명령을 사용하는 것입니다. 이는 현재 모든 최신/괜찮은 FTP 서버에서 지원되어야 합니다.

import ftplib
f = ftplib.FTP()
f.connect("localhost")
f.login()
ls = []
f.retrlines('MLSD', ls.append)
for entry in ls:
    print entry

위의 코드는 다음과 같이 인쇄됩니다.

modify=20110723201710;perm=el;size=4096;type=dir;unique=807g4e5a5; tests
modify=20111206092323;perm=el;size=4096;type=dir;unique=807g1008e0; .xchat2
modify=20111022125631;perm=el;size=4096;type=dir;unique=807g10001a; .gconfd
modify=20110808185618;perm=el;size=4096;type=dir;unique=807g160f9a; .skychart
...

Python 3.3부터 ftplib는 이를 수행하기 위한 특정 방법을 제공합니다:

파일 이름, 마지막 수정 스탬프, 파일 크기 등을 얻으려고 시도하는 동안 여기에서 길을 찾았고 내 코드를 추가하고 싶었습니다.구문 분석을 위한 루프를 작성하는 데 몇 분 밖에 걸리지 않았습니다. ftp.dir(dir_list.append) Python std lib를 사용하는 것과 같은 것 strip() (텍스트 줄을 정리하기 위해) 그리고 split() 배열을 생성합니다.

ftp = FTP('sick.domain.bro')
ftp.login()
ftp.cwd('path/to/data')

dir_list = []
ftp.dir(dir_list.append)

# main thing is identifing which char marks start of good stuff
# '-rw-r--r--   1 ppsrt    ppsrt      545498 Jul 23 12:07 FILENAME.FOO
#                               ^  (that is line[29])

for line in dir_list:
   print line[29:].strip().split(' ') # got yerself an array there bud!
   # EX ['545498', 'Jul', '23', '12:07', 'FILENAME.FOO']

레이아웃에 대한 표준은 없습니다. LIST 응답.가장 많이 사용되는 레이아웃을 처리하려면 코드를 작성해야 합니다.저는 리눅스부터 시작하겠습니다. ls 그리고 윈도우 서버 DIR 형식.하지만 거기에는 다양한 종류가 있습니다.

다시 nlst 메서드(결과 반환 NLST 명령) 더 긴 목록을 구문 분석할 수 없는 경우.보너스 포인트를 얻으려면 다음을 치트하세요.아마도 알려진 파일 이름이 포함된 줄에서 가장 긴 숫자는 해당 파일의 길이일 것입니다.

MLSD를 지원하지 않는 FTP 서버(Rackspace Cloud Sites 가상 서버)에 문제가 생겼습니다.하지만 파일 이름뿐만 아니라 크기, 타임스탬프 등 여러 파일 정보 필드가 필요하므로 DIR 명령을 사용해야 합니다.이 서버에서 DIR의 출력은 OP의 출력과 매우 유사합니다.누군가에게 도움이 된다면, 파일 이름, 크기 및 타임스탬프를 얻기 위해 그러한 출력의 한 줄을 구문 분석하는 작은 Python 클래스가 있습니다.

날짜/시간 가져오기

class FtpDir:
    def parse_dir_line(self, line):
        words = line.split()
        self.filename = words[8]
        self.size = int(words[4])
        t = words[7].split(':')
        ts = words[5] + '-' + words[6] + '-' + datetime.datetime.now().strftime('%Y') + ' ' + t[0] + ':' + t[1]
        self.timestamp = datetime.datetime.strptime(ts, '%b-%d-%Y %H:%M')

이식성이 좋지는 않지만 다양한 FTP 서버를 처리하기 위해 확장하거나 수정하기는 쉽습니다.

이것은 Python 문서에서 가져온 것입니다.

>>> from ftplib import FTP_TLS
>>> ftps = FTP_TLS('ftp.python.org')
>>> ftps.login()           # login anonymously before securing control 
channel
>>> ftps.prot_p()          # switch to secure data connection
>>> ftps.retrlines('LIST') # list directory content securely
total 9
drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 .
drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 ..
drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 bin
drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 etc
d-wxrwxr-x   2 ftp      wheel        1024 Sep  5 13:43 incoming
drwxr-xr-x   2 root     wheel        1024 Nov 17  1993 lib
drwxr-xr-x   6 1094     wheel        1024 Sep 13 19:07 pub
drwxr-xr-x   3 root     wheel        1024 Jan  3  1994 usr
-rw-r--r--   1 root     root          312 Aug  1  1994 welcome.msg

그것은 내 코드에 도움이 되었습니다.

어떤 종류의 파일만 펠터링하고 각 줄마다 테스트하는 조건을 추가하여 화면에 표시하려고 했을 때.

이와 같이

elif command == 'ls':
    print("directory of ", ftp.pwd())
    data = []
    ftp.dir(data.append)

    for line in data:
        x = line.split(".")
        formats=["gz", "zip", "rar", "tar", "bz2", "xz"]
        if x[-1] in formats:
            print ("-", line)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top