Seite 1 von 1
csv Dateien herunterladen
Verfasst: Sonntag 12. Januar 2025, 18:57
von Schlangenmensch
Guten Abend,
ich habe vor kurzem einen Wasserzähler mit vorbereiteter AI on the EDGE Software in Betrieb genommen. Alles funktioniert bis jetzt einwandfrei. Nun wollte ich jedoch die täglich gespeicherten Daten vom "Fileserver" herunterladen.
Leider muß ich jede einzelne Datei (data_2025-01-01) usw. per Ziel speichern unter über das WLAN herunterladen.
Nun wollte ich mit einem kleinen Python-Script die Dateien automatisch nacheinander herunterladen, jedoch fehlt mir hierzu die Idee, wie ich das Datum in der URL sowie am Zielort erhöhen kann.
Bis jetzt bin ich nur zum Download einzelner csv.Dateien gekommen.
hat hier jemand einen Tip für mich?
Code: Alles auswählen
import requests
req = requests.get('http://192.168.178.33/fileserver/log/data/data_2025-01-03.csv')
url_content = req.content
with open("/home/****/****/Wasserzähler/data_2025-01-03.csv", 'wb') as csv_file:
csv_file.write(url_content)
Re: csv Dateien herunterladen
Verfasst: Sonntag 12. Januar 2025, 19:20
von sparrow
Formatieren einer Zeichenkette: f-Strings.
Alles um Datum und Zeit findest du im datetime Modul. Auf ein bestehendes Datum kannst du einfach ein timdelta mit einem Tag addieren.
Code: Alles auswählen
>>> from datetime import date as Date
>>> from datetime import timedelta as TimeDelta
>>> today = Date.today()
>>> tomorrow = today + TimeDelta(days=1)
>>> print(tomorrow)
2025-01-13
>>>
Re: csv Dateien herunterladen
Verfasst: Sonntag 12. Januar 2025, 19:35
von Schlangenmensch
Danke für die schnelle Antwort, jetzt muß ich es "nur" noch hinbekommen die URL bzw. den Tag im Datum nach einem Schleifendurchlauf zu erhöhen.
Ich wurstel mich mal durch.

Re: csv Dateien herunterladen
Verfasst: Sonntag 12. Januar 2025, 19:44
von Dennis89
Hallo,
ergänzend der Link zur
Doku
Grüße
Dennis
Re: csv Dateien herunterladen
Verfasst: Montag 13. Januar 2025, 14:08
von DeaD_EyE
Code: Alles auswählen
from datetime import date as Date
from pathlib import Path
from urllib.request import URLError, urlopen
def download_by_date(date: Date):
file = f"data_{date}.csv"
url = f"http://192.168.178.33/fileserver/log/data/{file}"
# Angaben korrigieren
server_file = Path.home().joinpath("XXXX", "Wasserzähler", file)
print(f"{file=}")
print(f"{url=}")
print(f"{server_file=}")
try:
response = urlopen(url)
except URLError:
print(f"Konnte keine Verbindung zum Server aufbauen")
return
if server_file.exists():
print("Datei existiert bereits auf dem Server und wird nicht heruntergeladen")
return
with server_file.open("w") as fd:
while chunk := response.read(1024):
fd.write(chunk)
if __name__ == "__main__":
heute = Date.today()
download_by_date(heute)
Das Modul csv wird für den Download nicht benötigt. Wenn man csv lesen oder schreiben will, benötigt man das Modul csv.
Für den Download kann man auch urllib.request.urlopen verwenden. Ist geschmackssache. Das Modul requests ist halt eine weitere Abhängigkeit.
Re: csv Dateien herunterladen
Verfasst: Donnerstag 16. Januar 2025, 16:33
von Schlangenmensch
Vielen Dank für die Lösung.
Hätte man auch die URL in einer Liste speichern können und den Tag über ne Schleife je um 1 erhöhen und im Anschluß die Dateien nacheinander zu speichern? Ich möchte die Daten sowieseo nur pro Monat ziehen.
Wäre vermutlich totaler Murks, würde mich jedoch interessieren.
Re: csv Dateien herunterladen
Verfasst: Donnerstag 16. Januar 2025, 17:57
von DeaD_EyE
gibt immer das aktuelle Datum aus.
Mit timedelta und datetime kann man auch addieren und subtrahieren.
Im alten Code sind übrigens noch Fehler drin. Unter anderem wird die Datei im Text-Modus geöffnet, was falsch ist, da response.read(...) bytes ausgibt. Mit dem alten Code müsste ein TypeError ausgelöst werden.
Hier ein Beispiel, um das Datum zu inkrementieren und mehrere Dateien herunterzuladen.
Code: Alles auswählen
from datetime import date as Date
from datetime import timedelta as TimeDelta
from http.client import HTTPResponse
from pathlib import Path
from urllib.error import URLError
from urllib.request import urlopen
def download_file(response: HTTPResponse, file: Path):
# im alten Beispiel habe ich das b vergessen
# dann wird die Datei im Textmodus geöffnet
# und erwartet dann str
# aber response.read(...) liefert bytes zurück,
# also muss man auch bytes schreiben
with file.open("wb") as fd:
while chunk := response.read(1024):
fd.write(chunk)
def download_range(from_date: Date, to_date: Date):
ONE_DAY = TimeDelta(days=1)
server_path = Path.home().joinpath("XXXX", "Wasserzähler")
current_date = from_date
while from_date <= current_date <= to_date:
file = f"data_{current_date}.csv"
url = f"http://192.168.178.33/fileserver/log/data/{file}"
server_file = server_path / file
print(f"{file=}")
print(f"{url=}")
print(f"{server_file=}")
try:
response = urlopen(url, timeout=2)
except URLError:
print(f"Konnte keine Verbindung zum Server aufbauen:", url, end="\n\n")
current_date += ONE_DAY
continue
if server_file.exists():
print(
f"Datei '{server_file}' existiert bereits auf dem Server und wird nicht heruntergeladen",
end="\n\n",
)
current_date += ONE_DAY
continue
download_file(response, server_file)
current_date += ONE_DAY
print()
if __name__ == "__main__":
bis = Date.today()
von = bis - TimeDelta(days=31)
download_range(von, bis)
Re: csv Dateien herunterladen
Verfasst: Donnerstag 16. Januar 2025, 18:22
von Schlangenmensch
Nochmals vielen herzlichen Dank für die verbesserte Lösung. Ich werde sie bei Gelegenheit testen, versuche aber erst einmal meinen Murks zu Ende zu bringen um zu sehen ob das überhaupt auch funktioniert hätte.

Re: csv Dateien herunterladen
Verfasst: Donnerstag 16. Januar 2025, 19:03
von Sirius3
@DeaD_EyE: jetzt hast Du ein wunderbares Beispiel geliefert, warum man `continue` nicht verwenden sollte. Kann man Dir ja hundert mal schreiben, ich hoffe jetzt, dass Du es an Deinem eigenen Code selbst erkennst.
Es ist nicht nötig, shutil.copyfileobj nochmal nachzuprogrammieren.
Konstanten definiert man normalerweise am Anfang der Datei, damit man sie leicht finden und anpassen kann.
In der while-Schleife kann per Definition niemals die untere Bedingung falsch sein.
Im if-__name__-Block sollte wirklich nur ein Funktionsaufruf stehen.
Berücksichtig man das alles, kommt man ungefähr hier raus:
Code: Alles auswählen
from datetime import date as Date, timedelta as TimeDelta
from pathlib import Path
from urllib.error import URLError
from urllib.request import urlopen
from shutil import copyfileobj
ONE_DAY = TimeDelta(days=1)
SERVER_PATH = Path.home() / "XXXX" / "Wasserzähler"
URL = "http://192.168.178.33/fileserver/log/data/"
def download_range(from_date, to_date):
current_date = from_date
while current_date <= to_date:
file = f"data_{current_date}.csv"
url = f"{URL}/{file}"
server_file = server_path / file
print(f"{file=}")
print(f"{url=}")
print(f"{server_file=}")
try:
response = urlopen(url, timeout=2)
except URLError:
print("Konnte keine Verbindung zum Server aufbauen:", url)
else:
if server_file.exists():
print(
f"Datei '{server_file}' existiert bereits auf dem Server und wird nicht heruntergeladen"
)
else:
with server_file.open("wb") as fd:
copyfileobj(response, fd)
current_date += ONE_DAY
print()
def main():
bis = Date.today()
von = bis - TimeDelta(days=31)
download_range(von, bis)
if __name__ == "__main__":
main()
Re: csv Dateien herunterladen
Verfasst: Donnerstag 16. Januar 2025, 20:43
von DeaD_EyE
@Sirius3 ich weiß, dass continue in diesem Fall nicht ideal war, da ich 2-mal die gleiche Zeile Code kopieren musste. Ist mir aber egal, da ich keine Zeit mehr hatte und fertig werden wollte. Du hast ja meine Fehler korrigiert und das reicht doch aus.