@aaron: Wenn man Python 2 und 3 unterstützen möchte sind zwei unabhängige Programme IMHO die letzte Wahl. Ich würde da eher eine Quelltextbasis schreiben die mit beiden Versionen läuft. Da gibt es auch Bibliotheken die dabei helfen, wie `future` oder `six`. Und bei HTTP-Kram das externe `requests` statt der `urllib*`-Module aus der Standardbibliothek.
Zur Ausnahmebehandlung: Ja so würde das ungefähr syntaktisch aussehen und nein das macht natürlich so keinen Sinn, ausser die Aufgabe ist tatsächlich nur: Mache eine Ausgabe wenn keine Ressource für 'some url' gefunden wird.
Statt deutschem Handbuch wäre Englisch lernen wahrscheinlich die bessere Alternative. Denn es wird keine gute und aktuelle deutsche Übersetzung der gesamten Python-Dokumentation geben. Schon gar nicht wenn man Bibliotheken ausserhalb der Standardbibliothek mit hinzu zieht. Auch Domänenwissen, beispielsweise über HTTP steht direkt in der Regel erst einmal in Englisch zur Verfügung. Ob es dafür dann Übersetzungen gibt und wie gut die sind…
Dateien herunterladen und in einem Verzeichnis ablegen
Ich habe jetzt folgendes versucht:
Der 404 Fehler und Not a gzipped file wird angezeigt. Jetzt sollte sich das Programm normal beenden, ohne den Traceback ... Ist die Idee jetzt richtig? Die Ausgabe sieht jetzt so aus:
Code: Alles auswählen
def pull_file(symbol, year, week):
try:
url = URL_TEMPLATE.format(symbol, year, week)
response = urllib2.urlopen(url)
return response.read()
except urllib2.HTTPError, e:
print e.code
except urllib2.URLError, e:
print e.args
Code: Alles auswählen
404
Traceback (most recent call last):
File "TickDataCsv27.py", line 85, in <module>
main()
File "TickDataCsv27.py", line 82, in main
fetch_single_week("EURCAD", 2017, 1)
File "TickDataCsv27.py", line 46, in fetch_single_week
print_data_length(data)
File "TickDataCsv27.py", line 32, in print_data_length
data = f.read()
File "/usr/lib64/python2.7/gzip.py", line 254, in read
self._read(readsize)
File "/usr/lib64/python2.7/gzip.py", line 296, in _read
self._read_gzip_header()
File "/usr/lib64/python2.7/gzip.py", line 190, in _read_gzip_header
raise IOError, 'Not a gzipped file'
IOError: Not a gzipped file
Zuletzt geändert von Anonymous am Donnerstag 23. März 2017, 15:15, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@aaron: das ist nicht richtig, weil Du ja im Fehlerfall nichts sinnvolles machst. An der Stelle muß also eine Fehlerbehandlung eine andere Exception werfen, die dann weiter oben verarbeitet werden kann, oder gleich ganz entfallen.
Gut ich werde jetzt das exepition handling in den Griff bekommen und dann die die Quelltextbasis für Python 2 und 3 erstellen.BlackJack hat geschrieben:@aaron: Wenn man Python 2 und 3 unterstützen möchte sind zwei unabhängige Programme IMHO die letzte Wahl. Ich würde da eher eine Quelltextbasis schreiben die mit beiden Versionen läuft. Da gibt es auch Bibliotheken die dabei helfen, wie `future` oder `six`. Und bei HTTP-Kram das externe `requests` statt der `urllib*`-Module aus der Standardbibliothek.
Meine Englischkenntnisse sind relativ gut. Es ist diese Bequemlichkeit, die sich gern bei mir einschleicht. Ein deutschsprachiges Buch läßt sich für mich leichter lesen als ein englischsprachiges Buch.Zur Ausnahmebehandlung: Ja so würde das ungefähr syntaktisch aussehen und nein das macht natürlich so keinen Sinn, ausser die Aufgabe ist tatsächlich nur: Mache eine Ausgabe wenn keine Ressource für 'some url' gefunden wird.
Statt deutschem Handbuch wäre Englisch lernen wahrscheinlich die bessere Alternative. Denn es wird keine gute und aktuelle deutsche Übersetzung der gesamten Python-Dokumentation geben. Schon gar nicht wenn man Bibliotheken ausserhalb der Standardbibliothek mit hinzu zieht. Auch Domänenwissen, beispielsweise über HTTP steht direkt in der Regel erst einmal in Englisch zur Verfügung. Ob es dafür dann Übersetzungen gibt und wie gut die sind…
Bei guten Englischkenntnissen ist dies reine Übungssache. Stürz Dich daher am besten direkt in die englischsprachigen Dokumentationen. Der Markt für deutschsprachige Dokumentationen ist zu klein, um für Autoren wirklich attraktiv zu sein. Und daran wird sich vermutlich auch nichts ändern.aaron hat geschrieben:Meine Englischkenntnisse sind relativ gut. Es ist diese Bequemlichkeit, die sich gern bei mir einschleicht. Ein deutschsprachiges Buch läßt sich für mich leichter lesen als ein englischsprachiges Buch.
Hallo ich bin immer noch nicht weiter mit dem error handling. Nach stundenlangem Googeln und ausprobieren habe ich kein brauchbares Ergebnis. Ich brauche dringend einen Tip. Welche Funktion(en) muß ich anfassen? Danke für die Hilfe
Auch wenn ihr den Speicherfehler beim Herunterladen der Dateien nicht bestätigt habt, so würde ich gern das Shutil Modul verwenden.
Ich habe in der folgenden Funktion die letzte Zeile verändert. von output.write(data) nach shutil.copyfileobj(data, output). Leider ohne Erfolg. Habe die Dokumentation und Google schon mehrfach danach befragt. Ich kann die Fehlermeldung nicht richtig deuten. Schaut euch bitte das Traceback einmal an.
Hier die Fehlermeldung:
Ich habe in der folgenden Funktion die letzte Zeile verändert. von output.write(data) nach shutil.copyfileobj(data, output). Leider ohne Erfolg. Habe die Dokumentation und Google schon mehrfach danach befragt. Ich kann die Fehlermeldung nicht richtig deuten. Schaut euch bitte das Traceback einmal an.
Code: Alles auswählen
def save_file(symbol, year, week, data):
filename = generate_filename(symbol, year, week)
print(filename)
if not os.path.exists(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
with open(filename, "wb") as output:
shutil.copyfileobj(data, output)
Code: Alles auswählen
Traceback (most recent call last):
File "TickDataCsv27.py", line 82, in <module>
main()
File "TickDataCsv27.py", line 79, in main
fetch_single_week("EURUSD", 2017, 11)
File "TickDataCsv27.py", line 44, in fetch_single_week
save_file(symbol, year, week, data)
File "TickDataCsv27.py", line 37, in save_file
shutil.copyfileobj(data, output)
File "/usr/lib64/python2.7/shutil.py", line 49, in copyfileobj
buf = fsrc.read(length)
AttributeError: 'str' object has no attribute 'read'
Hier habe ich einen neuen Ansatz. Leider funktioniert auch dieser nicht richtig. shutil.copy(filename, "data") ist auch falsch. shutil.copy(filename, "filenme") funktioniert auch nicht.
Code: Alles auswählen
def save_file(symbol, year, week, data):
filename = generate_filename(symbol, year, week)
print(filename)
if not os.path.exists(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
with open(filename, "wb") as output:
shutil.copy(filename, "data")
output.write(data)
@aaron: Solange Du die Datei vor dem Speichern auf Festplatte zweimal lesen musst/willst wird Dir das eh nicht helfen, denn solange musst Du die Datei auf jeden Fall einmal komplett im Speicher halten damit die Daten ein zweites mal gelesen werden können, weil ein Dateiobjekt das die Daten aus dem Netz überträgt nicht ”seekable” ist. Das könntest Du nur umgehen wenn Du kopieren von Netz auf Platte und ermitteln der unkomprimierten Grösse in einem Schritt machst, was aber eigenen Code erfordert der ein kleines bisschen komplizierter wird als das was Du bis jetzt da machst.
Ich sehe bei den Dateigrössen auch keinen Grund warum das zu einem `MemoryError` führen sollte. Selbst bei einem 32-Bit-Python dürfte das nicht passieren, bei einem 64-Bit-Python und dem RAM schon gar nicht.
Wo Du bei der Verarbeitung Speicher sparen kannst ist beim ermitteln der unkomprimierten Grösse. Das musst Du aber selber ausprogrammieren, denn da wird ja nicht einfach nur kopiert, da musst Du die Längen der Blöcke aufsummieren.
Edit: Am einfachsten vom Code her wäre es wohl `shutil` zu verwenden um direkt von dem `Response`-Dateiobjekt in ein Dateiobjekt auf Platte kopieren zu lassen und zur Bestimmung der unkomprimierten Grösse die Datei erneut, blockweise, von Platte zu lesen. Bei dem RAM den Du hast dürfte das lesen ”von Platte” auf ein lesen aus dem Cache hinauslaufen, also auch keinen grossen Geschwindigkeitsverlust bedeuten.
Ich sehe bei den Dateigrössen auch keinen Grund warum das zu einem `MemoryError` führen sollte. Selbst bei einem 32-Bit-Python dürfte das nicht passieren, bei einem 64-Bit-Python und dem RAM schon gar nicht.
Wo Du bei der Verarbeitung Speicher sparen kannst ist beim ermitteln der unkomprimierten Grösse. Das musst Du aber selber ausprogrammieren, denn da wird ja nicht einfach nur kopiert, da musst Du die Längen der Blöcke aufsummieren.
Edit: Am einfachsten vom Code her wäre es wohl `shutil` zu verwenden um direkt von dem `Response`-Dateiobjekt in ein Dateiobjekt auf Platte kopieren zu lassen und zur Bestimmung der unkomprimierten Grösse die Datei erneut, blockweise, von Platte zu lesen. Bei dem RAM den Du hast dürfte das lesen ”von Platte” auf ein lesen aus dem Cache hinauslaufen, also auch keinen grossen Geschwindigkeitsverlust bedeuten.
Danke für die schnelle Antwort. Wie fasse ich das Problem am besten an? Könntest du mir ein wenig unter die Arme greifen? In welcher Funktion soll ich shutil verwenden? Das ist mit Sicherheit absolut logisch und richtig was du vorschlägst, nur mit der Umsetzung hapert es hier.
Edit: Am einfachsten vom Code her wäre es wohl `shutil` zu verwenden um direkt von dem `Response`-Dateiobjekt in ein Dateiobjekt auf Platte kopieren zu lassen und zur Bestimmung der unkomprimierten Grösse die Datei erneut, blockweise, von Platte zu lesen. Bei dem RAM den Du hast dürfte das lesen ”von Platte” auf ein lesen aus dem Cache hinauslaufen, also auch keinen grossen Geschwindigkeitsverlust bedeuten.
Bitte schaut Euch noch einmal meinen Versuch shutil zum Laufen zu bringen an. Es funktioniert nicht. Ich bin für jede Hilfe dankbar. Baue ich das Modul in der richtigen Funktion ein? Ich habe hier ein Verständnisproblem, trotz lesen der Dokumentation.
Code: Alles auswählen
def save_file(symbol, year, week, data):
filename = generate_filename(symbol, year, week)
print(filename)
url = URL_TEMPLATE.format(symbol, year, week)
response = requests.get(url, stream = True)
if not os.path.exists(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
with open(filename, "wb") as output:
response.raw.decode_content = True
shutil.copyfileobj(response.raw, output)
output.write(data)
Zuletzt geändert von Anonymous am Donnerstag 30. März 2017, 12:48, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Ich finde die Funktion überladen, warum rufst du dort Daten ab? Die Funktion save_file sollte meines Erachtens nur (!) das Speichern als Datei erledigen und den Rest als Parameter bekommen haben. Kannst Du mal die Fehlermeldung posten, das wäre m. E. sehr hilfreich.
Vollständiges Tool unter
https://github.com/joergklein/Datawareh ... DataCsv.py
Ich finde das Tool dort leichter zu lesen. Hast Du mal versucht ganz auf shutil zu verzichten? Ich nutze es nur zum Verschieben oder Kopieren von Dateien, nicht aber im Download von csv-Files...
Vollständiges Tool unter
https://github.com/joergklein/Datawareh ... DataCsv.py
Ich finde das Tool dort leichter zu lesen. Hast Du mal versucht ganz auf shutil zu verzichten? Ich nutze es nur zum Verschieben oder Kopieren von Dateien, nicht aber im Download von csv-Files...
@pixewakb: Ja hat er versucht, und es sind *grosse* Dateien, deswegen kann ja der Tipp von hier die nicht komplett in den Speicher herunter zu laden sondern beim herunterladen schon in eine Datei zu speichern. Das kann man nun selbst schreiben, oder man nimmt `shutil` dafür weil das Problem da ja schon mal gelöst wurde.
Für mich liest sich folgender Abschnitt im Code:
so, als würde er die Aufgabe einmal mit with open... und einmal mit shutil zu lösen versuchen. Ich habe beide Sachen selbst noch nie kombiniert? csv-files downloaden und abspeichern mache ich "häufig", aber die Dateien sind kleiner und es gibt eine fertige Funktion, die das für mich löst. Ich meine, dass da pandas verbaut wäre (habe ich nicht programmiert, habe ich mir noch nicht genauer angesehen).
Als ich das noch selbst gemacht habe, dann habe ich das mittels requests geladen und dann direkt als string-Daten auf die Festplatte gepackt. Das ist jetzt aber sicher mehr als ein Jahr her.
Code: Alles auswählen
with open(filename, "wb") as output:
response.raw.decode_content = True
shutil.copyfileobj(response.raw, output)
output.write(data)
Als ich das noch selbst gemacht habe, dann habe ich das mittels requests geladen und dann direkt als string-Daten auf die Festplatte gepackt. Das ist jetzt aber sicher mehr als ein Jahr her.
@pixewakb: Du musst die Ausgabedatei ja mit `open()` öffnen — wie willst Du sonst die Zieldatei erstellen? Also braucht man `open()` *und* `shutil`.
Da ist natürlich offensichtlich noch ein Quelltextfragment enthalten das keinen Sinn (mehr) macht, aber auch zu einer sehr eindeutigen Fehlermeldung führen wird, die eigentlich durch nachdenken sehr schnell dazu führen sollte, das man erkennt, das das keinen Sinn (mehr) macht. Vermutlich wird aber davor noch ein anderer Fehler auftreten. „Es funktioniert nicht.“ ist mir aber zu vage als Fehlerbeschreibung das ich da jetzt anfangen wollte zu raten.
Da ist natürlich offensichtlich noch ein Quelltextfragment enthalten das keinen Sinn (mehr) macht, aber auch zu einer sehr eindeutigen Fehlermeldung führen wird, die eigentlich durch nachdenken sehr schnell dazu führen sollte, das man erkennt, das das keinen Sinn (mehr) macht. Vermutlich wird aber davor noch ein anderer Fehler auftreten. „Es funktioniert nicht.“ ist mir aber zu vage als Fehlerbeschreibung das ich da jetzt anfangen wollte zu raten.
Vielen Dank für die Rückmeldung. Wie gesagt, die ersten Dateien sind wieder ohne Probleme heruntergeladen worden. Ich habe jetzt noch einmal die Funktion umgeschrieben. Diese sieht jetzt so aus:
Das ist die Fehlermeldung:
Code: Alles auswählen
def save_file(symbol, year, week, data):
filename = generate_filename(symbol, year, week)
print(filename)
url = URL_TEMPLATE.format(symbol, year, week)
response = requests.get(url, stream = True)
if not os.path.exists(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
response.raw.decode_content = True
shutil.copyfileobj(response.raw, data)
output.write(data)
Code: Alles auswählen
Traceback (most recent call last):
File "TickDataCsv.py", line 85, in <module>
main()
File "TickDataCsv.py", line 80, in main
fetch_whole_year(symbol, 2016)
File "TickDataCsv.py", line 57, in fetch_whole_year
print_data_length(data)
File "TickDataCsv.py", line 29, in print_data_length
data = f.read()
File "/usr/lib/python2.7/gzip.py", line 261, in read
self._read(readsize)
File "/usr/lib/python2.7/gzip.py", line 320, in _read
self._add_read_data( uncompress )
File "/usr/lib/python2.7/gzip.py", line 338, in _add_read_data
self.extrabuf = self.extrabuf[offset:] + data
MemoryError
Zuletzt geändert von Anonymous am Samstag 1. April 2017, 16:44, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
@aaron: Der Traceback passt nicht nur nicht zur gezeigten `save_file()`-Funktion, denn die kommt dort überhaupt nicht vor — die `save_file()`-Funktion führt auch zu fehlern, aber anderen. Das heisst die wird gar nicht verwendet wenn diese Ausnahmen nicht kommen.
Hier noch einmal die ursprüngliche Funktion, ohne die Änderung. Gebt mir doch bitte einmal einen Tip. Vielleicht suche ich auch in der falschen Funktion.
Hier das Traceback
Code: Alles auswählen
def save_file(symbol, year, week, data):
filename = generate_filename(symbol, year, week)
print(filename)
if not os.path.exists(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
with open(filename, "wb") as output:
output.write(data)
Code: Alles auswählen
Traceback (most recent call last):
File "TickDataCsv.py", line 82, in <module>
main()
File "TickDataCsv.py", line 77, in main
fetch_whole_year(symbol, 2016)
File "TickDataCsv.py", line 54, in fetch_whole_year
print_data_length(data)
File "TickDataCsv.py", line 29, in print_data_length
data = f.read()
File "/usr/lib/python2.7/gzip.py", line 261, in read
self._read(readsize)
File "/usr/lib/python2.7/gzip.py", line 320, in _read
self._add_read_data( uncompress )
File "/usr/lib/python2.7/gzip.py", line 338, in _add_read_data
self.extrabuf = self.extrabuf[offset:] + data
MemoryError