=> Ich habe diese Webseite beim googlen gefunden, um zu sehen, ob eine Datei mit ftplib in Python existiert. Folgendes habe ich herausgefunden (hoffe, es hilft jemandem):
=> Beim Versuch, nicht existierende Dateien/Verzeichnisse aufzulisten, löst ftplib eine Ausnahme aus. Auch wenn das Hinzufügen eines try/exception-Blocks eine gängige Praxis und eine gute Idee ist, würde ich es vorziehen, wenn meine FTP-Skripte die Datei (en) erst herunterladen, nachdem sie sich vergewissert haben, dass sie existieren. Dies hilft, meine Skripte einfacher zu halten - zumindest wenn ein Verzeichnis auf dem FTP-Server aufgelistet werden kann.
Zum Beispiel hat der Edgar FTP-Server mehrere Dateien, die unter dem Verzeichnis/edgar/daily-index/gespeichert sind. Jede Datei hat den Namen "master.YYYYMMDD.idx". Es gibt keine Garantie, dass eine Datei für jedes Datum existiert (JJJJMMTT) - es gibt keine Datei vom 24. November 2013, aber es gibt eine Datei vom 22. November 2013. Wie funktioniert das Listing in diesen beiden Fällen?
# 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
Wie erwartet, wird beim Auflisten einer nicht vorhandenen Datei eine Ausnahme generiert.
=> Da ich, dass der Edgar FTP-Server kennen sicherlich das Verzeichnis haben/edgar/daily-Index/kann mein Skript tun das aufgrund nicht vorhandenen Dateien erhöhen Ausnahmen zu vermeiden, folgende:
a) Liste dieser Verzeichnis.
b) laden Sie die erforderlichen Datei (en) herunter, wenn sie in dieser Liste vorhanden sind - Um die Liste zu überprüfen, führe ich normalerweise eine regexp-Suche in der Liste der Zeichenfolgen durch, die der Auflistungsvorgang zurückgibt.
Zum Beispiel versucht dieses Skript, Dateien für die letzten drei Tage herunterzuladen. Wenn eine Datei für ein bestimmtes Datum gefunden wird, wird sie heruntergeladen, sonst passiert nichts.
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
)
=> Interessanterweise gibt es Situationen, in denen wir ein Verzeichnis auf dem FTP-Server nicht auflisten können. Der edgar FTP-Server zum Beispiel verbietet die Auflistung auf/edgar/data, weil er viel zu viele Unterverzeichnisse enthält. In solchen Fällen wäre ich nicht in der Lage, den hier beschriebenen Ansatz "Auflisten und Prüfen auf Vorhandensein" zu verwenden - in diesen Fällen müsste ich die Ausnahmebehandlung in meinem Downloader-Skript verwenden, um von nicht vorhandenen Datei-/Verzeichniszugriffsversuchen wiederherzustellen.
Dies sagt Ihnen nicht, ob es eine * Datei * (anstatt eines Verzeichnisses) namens 'public_html' gibt. –
wenn nicht ("public_html" in f für f in Dateiliste): print "No public_html" anderes: # etwas tun oder: public = [f für f in Dateiliste, wenn "public_html" in f] wenn nicht öffentlich: print „No public_html“ anderes: für f in der Öffentlichkeit: # tun Sie etwas – hughdbrown
Stattdessen Befehl „LIST“ zu senden, die eine Linie voller Informationen über jede Datei zurückgibt, und testet dann ‚, wenn Dateiname In f 'könnten Sie den Befehl "NLST" senden, der nur den Dateinamen für jede Datei zurückgibt. Siehe http://docs.python.org/library/ftplib.html#ftplib.FTP.retrlines –