2009-07-08 15 views
13

मैं इस स्क्रिप्ट का उपयोग कर रहा कनेक्ट करने के लिए एफ़टीपी सर्वर और सूची उपलब्ध निर्देशिका नमूने के लिए:ftp निर्देशिका मौजूद होने पर पायथन जांच कैसे करें?

from ftplib import FTP 
ftp = FTP('ftp.cwi.nl') # connect to host, default port (some example server, i'll use other one) 
ftp.login()    # user anonymous, passwd [email protected] 
ftp.retrlines('LIST')  # list directory contents 
ftp.quit() 

मैं ftp.retrlines ('LIST') उत्पादन का उपयोग कैसे करूँ यदि निर्देशिका (उदाहरण के लिए) public_html मौजूद है की जाँच करने के, यदि यह सीडी मौजूद है और फिर कुछ अन्य कोड निष्पादित करें और बाहर निकलें; अगर तुरंत कोड निष्पादित नहीं करते हैं और बाहर निकलें?

उत्तर

9

आप एक सूची का उपयोग कर सकते हैं। उदाहरण

import ftplib 
server="localhost" 
user="user" 
password="[email protected]" 
try: 
    ftp = ftplib.FTP(server)  
    ftp.login(user,password) 
except Exception,e: 
    print e 
else:  
    filelist = [] #to store all files 
    ftp.retrlines('LIST',filelist.append) # append to list 
    f=0 
    for f in filelist: 
     if "public_html" in f: 
      #do something 
      f=1 
    if f==0: 
     print "No public_html" 
     #do your processing here 
+0

यह आपको नहीं बताएगा कि * public_html' नामक एक * फ़ाइल * (निर्देशिका के बजाय) है या नहीं। –

+0

नहीं तो किसी भी ("public_html" filelist में च के लिए च में): प्रिंट "नहीं public_html" और : # कुछ करना या: सार्वजनिक = [च filelist में च के लिए करता है, तो "public_html" च में] नहीं तो जनता: प्रिंट "नहीं public_html" और : सार्वजनिक रूप से च के लिए : # बजाय कमांड "सूची" है, जो एक लाइन प्रत्येक फ़ाइल के बारे में जानकारी से भरा रिटर्न भेजकर और फिर परीक्षण के बारे में कुछ – hughdbrown

+7

करो 'अगर फ़ाइल नाम एफ में, आप "एनएलएसटी" कमांड भेज सकते हैं, जो सिर्फ प्रत्येक फ़ाइल के लिए फ़ाइल नाम देता है। Http://docs.python.org/library/ftplib.html#ftplib.FTP.retrlines –

3

उदाहरण ghostdog74 के जवाब से जुड़ी एक बग का एक सा है: तो आप की तरह

drwxrwxrwx 4 5063  5063   4096 Sep 13 20:00 resized 

कुछ पाने सूची वापस पहुंचने के लिए प्रतिक्रिया की पूरी लाइन है, इसका मतलब यह है कि यदि आपके निर्देशिका का नाम कुछ '50' जैसा है (जो मेरे मामले में था), आपको झूठी सकारात्मक मिलेगी। मैं इस संभाल करने के लिए कोड संशोधित:

def directory_exists_here(self, directory_name): 
    filelist = [] 
    self.ftp.retrlines('LIST',filelist.append) 
    for f in filelist: 
     if f.split()[-1] == directory_name: 
      return True 
    return False 

N.B., इस एक FTP आवरण वर्ग मैंने लिखा और self.ftp वास्तविक FTP कनेक्शन है अंदर है।

1

टॉम सही है, लेकिन किसी ने उसे वोट दिया है, हालांकि ghostdog74 को वोट देने वाली संतुष्टि के लिए मैं इस कोड को मिलाकर लिखूंगा, मेरे लिए काम करता है, आपके लिए काम करना चाहिए।

import ftplib 
server="localhost" 
user="user" 
uploadToDir="public_html" 
password="[email protected]" 
try: 
    ftp = ftplib.FTP(server)  
    ftp.login(user,password) 
except Exception,e: 
    print e 
else:  
    filelist = [] #to store all files 
    ftp.retrlines('NLST',filelist.append) # append to list 
    num=0 
    for f in filelist: 
     if f.split()[-1] == uploadToDir: 
      #do something 
      num=1 
    if num==0: 
     print "No public_html" 
     #do your processing here 

सब से पहले अगर आप भूत कुत्ते विधि का पालन, भले ही आप कहते हैं कि निर्देशिका "सार्वजनिक" च में, तब भी जब यह does not मौजूद यह सच करने के लिए मूल्यांकन करेंगे क्योंकि शब्द सार्वजनिक "public_html" में मौजूद हैं तो thats जहां टॉम अगर स्थिति का उपयोग किया जा सकता है तो मैंने इसे में बदल दिया है अगर f.split() [- 1] == अपलोड करने के लिए:

इसके अलावा, अगर आप एक निर्देशिका का नाम somethig कि does not दर्ज मौजूद हैं, लेकिन कुछ फ़ाइलें और फ़ोल्डर मौजूद ghostdog74 द्वारा दूसरे पर अमल कभी नहीं होगा क्योंकि इसकी कभी नहीं 0 के रूप में पाश के लिए में च द्वारा ओवरराइड तो मैं चर बजाय संख्या का इस्तेमाल किया च की और वॉयला भलाई का पालन करता है ...

विनय और जोनाथन उन्होंने जो टिप्पणी की थी उसके बारे में सही हैं।

15

एनएसएलटी एफटीपी सर्वर में सभी फाइलों के लिए एक सरणी सूचीबद्ध करेगा। बस जांचें कि आपका फ़ोल्डर नाम है या नहीं।

from ftplib import FTP 
ftp = FTP('yourserver') 
ftp.login('username', 'password') 

folderName = 'yourFolderName' 
if folderName in ftp.nlst(): 
    #do needed task 
+1

यह अविश्वसनीय है क्योंकि एनएलएसटी फाइलों और निर्देशिकाओं के बीच अंतर नहीं करता है: यह आपको केवल 'नाम' की एक सूची देता है। –

+1

शायद वह निर्देशिका भी खोजना चाहता है? – Temere

+0

ध्यान दें कि यह फ़ाइल और निर्देशिका नामों की एक सूची देता है - पथ नहीं, इसलिए आपको 'usr' और 'bin' मिलेगा, लेकिन *** नहीं ***'/usr/bin' – Mawg

1

3.x nlst() विधि में बहिष्कृत किया गया है। इस कोड का उपयोग करें:

import ftplib 

remote = ftplib.FTP('example.com') 
remote.login() 

if 'foo' in [name for name, data in list(remote.mlsd())]: 
    # do your stuff 

list() कॉल की जरूरत है क्योंकि mlsd() एक जनरेटर वापस आती है और वे जाँच क्या उन में है का समर्थन नहीं करते (__contains__() विधि नहीं है)।

आप विधि के एक समारोह में [name for name, data in list(remote.mlsd())] सूची कंप को लपेट सकते हैं और इसे कॉल कर सकते हैं जब आपको केवल यह जांचने की आवश्यकता होगी कि कोई निर्देशिका (या फ़ाइल) मौजूद है या नहीं।

4

आप नियंत्रण कनेक्शन पर "एमएलएसटी पथ" भेज सकते हैं। कि प्रकार पथ (नोटिस 'type = निर्देशिका' यहाँ नीचे) की सहित एक लाइन वापस आ जाएगी:

250-Listing "/home/user": 
modify=20131113091701;perm=el;size=4096;type=dir;unique=813gc0004;/
250 End MLST. 

अजगर में अनुवाद किया है कि इन पंक्तियों के साथ कुछ किया जाना चाहिए:

import ftplib 
ftp = ftplib.FTP() 
ftp.connect('ftp.somedomain.com', 21) 
ftp.login() 
resp = ftp.sendcmd('MLST pathname') 
if 'type=dir;' in resp: 
    # it should be a directory 
    pass 

बेशक ऊपर दिया गया कोड 100% विश्वसनीय नहीं है और उसे 'वास्तविक' पार्सर की आवश्यकता होगी। आप ftplib.py में एमएलएसडी कमांड के कार्यान्वयन को देख सकते हैं जो बहुत समान है (एमएलएसडी एमएलएसटी से भिन्न है जिसमें डेटा कनेक्शन पर भेजा गया प्रतिक्रिया है लेकिन प्रेषित लाइनों का प्रारूप समान है): http://hg.python.org/cpython/file/8af2dc11464f/Lib/ftplib.py#l577

+0

मैं इसे ऊपर उठा रहा हूं, क्योंकि इसे ऐसा करने के लिए एक अच्छा तरीका लगता है। हां, मेरा विशेष होस्ट "500 अज्ञात कमांड" लौटाता है, इसलिए एफ़टीपी एफ़टीएटर – Mawg

1

=> मुझे यह वेब पेज मिला है कि यह जांचने के लिए कि क्या फ़ाइल पाइथन में ftplib का उपयोग कर मौजूद है या नहीं। निम्नलिखित मैंने पाया है (उम्मीद है कि यह किसी की मदद करता है):

=> गैर-मौजूद फ़ाइलों/निर्देशिकाओं को सूचीबद्ध करने का प्रयास करते समय, ftplib एक अपवाद उठाता है। भले ही कोशिश/ब्लॉक को छोड़कर एक मानक अभ्यास और एक अच्छा विचार है, मैं अपने एफ़टीपी स्क्रिप्ट को केवल यह सुनिश्चित करने के बाद फ़ाइल डाउनलोड करने के लिए पसंद करूंगा। यह मेरी स्क्रिप्ट को सरल रखने में मदद करता है - कम से कम जब FTP सर्वर पर निर्देशिका सूचीबद्ध करना संभव है।

उदाहरण के लिए, एडगर एफ़टीपी सर्वर में कई फाइलें हैं जो निर्देशिका/एडगर/दैनिक-अनुक्रमणिका/के अंतर्गत संग्रहीत हैं। प्रत्येक फ़ाइल को "मास्टर.YYYYMMDD.idx" पसंद किया गया है। इस बात की कोई गारंटी नहीं है कि प्रत्येक तारीख (YYYYMMDD) के लिए एक फ़ाइल मौजूद होगी - 24 नवंबर 2013 की कोई फ़ाइल नहीं है, लेकिन दिनांकित एक फ़ाइल है: 22 नवंबर 2013. इन दो मामलों में लिस्टिंग कैसे काम करती है?

# Code 
from __future__ import print_function 
import ftplib 

ftp_client = ftplib.FTP("ftp.sec.gov", "anonymous", "[email protected]") 
resp = ftp_client.sendcmd("MLST /edgar/daily-index/master.20131122.idx") 
print(resp) 
resp = ftp_client.sendcmd("MLST /edgar/daily-index/master.20131124.idx") 
print(resp) 

# Output 
250-Start of list for /edgar/daily-index/master.20131122.idx 
modify=20131123030124;perm=adfr;size=301580;type=file;unique=11UAEAA398; 
UNIX.group=1;UNIX.mode=0644;UNIX.owner=1019; 
/edgar/daily-index/master.20131122.idx 
250 End of list 

Traceback (most recent call last): 
File "", line 10, in <module> 
resp = ftp_client.sendcmd("MLST /edgar/daily-index/master.20131124.idx") 
File "lib/python2.7/ftplib.py", line 244, in sendcmd 
return self.getresp() 
File "lib/python2.7/ftplib.py", line 219, in getresp 
raise error_perm, resp 
ftplib.error_perm: 550 '/edgar/daily-index/master.20131124.idx' cannot be listed 

जैसा कि अपेक्षित है, एक गैर-मौजूद फ़ाइल सूचीबद्ध करना अपवाद उत्पन्न करता है।

=> के बाद से मैं जानता हूँ कि एडगर FTP सर्वर निश्चित रूप से निर्देशिका होगा/एडगर/दैनिक सूचकांक /, मेरी स्क्रिप्ट न के बराबर फाइलों की वजह से अपवादों को ऊपर उठाने से बचने के लिए निम्न कर सकते हैं:
क) इस सूची निर्देशिका।
बी) यदि आवश्यक हो तो आवश्यक फ़ाइल डाउनलोड करें यदि वे इस लिस्टिंग में मौजूद हैं - लिस्टिंग की जांच करने के लिए मैं आम तौर पर लिस्टिंग ऑपरेशन लौटने वाली तारों की सूची पर एक regexp खोज करता हूं।

उदाहरण के लिए यह स्क्रिप्ट पिछले तीन दिनों से फ़ाइलों को डाउनलोड करने का प्रयास करती है। अगर किसी निश्चित तारीख के लिए कोई फ़ाइल पाई जाती है तो यह डाउनलोड हो जाती है, और कुछ भी नहीं होता है।

import ftplib 
import re 
from datetime import date, timedelta 

ftp_client = ftplib.FTP("ftp.sec.gov", "anonymous", "[email protected]") 
listing = [] 
# List the directory and store each directory entry as a string in an array 
ftp_client.retrlines("LIST /edgar/daily-index", listing.append) 
# go back 1,2 and 3 days 
for diff in [1,2,3]: 
    today = (date.today() - timedelta(days=diff)).strftime("%Y%m%d") 
    month = (date.today() - timedelta(days=diff)).strftime("%Y_%m") 
    # the absolute path of the file we want to download - if it indeed exists 
    file_path = "/edgar/daily-index/master.%(date)s.idx" % { "date": today } 
    # create a regex to match the file's name 
    pattern = re.compile("master.%(date)s.idx" % { "date": today }) 
    # filter out elements from the listing that match the pattern 
    found = filter(lambda x: re.search(pattern, x) != None, listing) 
    if(len(found) > 0): 
    ftp_client.retrbinary(
     "RETR %(file_path)s" % { "file_path": file_path }, 
     open(
     './edgar/daily-index/%(month)s/master.%(date)s.idx' % { 
      "date": today 
     }, 'wb' 
    ).write 
    ) 

=> दिलचस्प बात यह है कि ऐसी स्थितियां हैं जहां हम FTP सर्वर पर निर्देशिका सूचीबद्ध नहीं कर सकते हैं। एडगर एफ़टीपी सर्वर, उदाहरण के लिए,/edgar/डेटा पर लिस्टिंग को अस्वीकार करता है क्योंकि इसमें बहुत अधिक उप-निर्देशिकाएं हैं। ऐसे मामलों में, मैं यहां वर्णित "अस्तित्व की सूची और जांच" दृष्टिकोण का उपयोग नहीं कर पाऊंगा - इन मामलों में मुझे गैर-मौजूद फ़ाइल/निर्देशिका पहुंच प्रयासों से पुनर्प्राप्त करने के लिए अपने डाउनलोडर स्क्रिप्ट में अपवाद हैंडलिंग का उपयोग करना होगा।

संबंधित मुद्दे