Wetterdaten aus Internet in Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Hallo Leute,

ich habe mal eine Frage. Wie kann man Wetterdaten aus dem Internet in Python einbinden? Ich habe schon das ein oder andere gelesen, aber bin daraus nicht viel schlauer geworden. Hat jmd einen fertigen Code, an dem ich mir das ganze mal zum Verständnis anschauen kann oder vlt ein verständliches Tutorial, welches das Vorgehen gut erklärt.


LG
__deets__
User
Beiträge: 14525
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wo kommen deine wetterdaten denn her? Das Internet ist ja ein großer und unübersichtlicher Ort. Und die Quelle bestimmt das Vorgehen.
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

so ganz allgemeine:

* Du registrierst dich bei einem Dienst, der Wetterdaten über eine webbasierte API bereitstellt (wie z.B. openweathermap.org)
* Du fragst die API mit einen entsprechenden Python-Modul (wie z.B. requests) und deinen Standortdaten ab.
* Du verarbeitest die gelieferten Daten in Python.

Um konkreter zu werden müsstest du schon zeigen a) was du gelesen hast, b) was du probiert hast, c) was nicht funktioniert hat.

Gruß, noisefloor
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Schritt eins mit dem Registrieren habe ich gemacht. Schritt 2 und 3 nicht. Das heißt ich werde mich jetzt mal dazu belesen...
Gibt es etwas, was ich wichtiges beachten muss? Und gibt es requests in Python 3, da habe ich nämlich mal beim ausprobieren eines fertigen codes den Fehler bekommen, das es das Modul nicht gibt.
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@No17: Das Modul gibt es weder *in* Python 2 noch *in* Python 3. Aber es gibt es *für* Python 2 und *für* Python 3. Man muss es halt installieren. Dann gibt es das auch. :-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Das habe ich auch gerade mitbekommen und es jetzt installiert. Trotzdem Danke für den Hinweis
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Ok ich habe jetzt ein klein wenig rumgespielt. Nach den ersten Schritten diese Tutorials https://www.dataquest.io/blog/python-api-tutorial/ hat alles geklappt. Wenn ich das jetzt aber abändere auf den Beispiellink von OpenweatherMap

Code: Alles auswählen

import requests



response = requests.get("https://api.openweathermap.org/data/2.5/weather?q={city name}")
print(response.content)
Also bei CityName habe ich zum Test einfach mal London eingesetzt. Dann kommt eine Antwort mit Verweis auf Fehler 401, welcher besagt das man quasi angemeldet sein muss, wenn ich das richtig verstehe oder irgendwie sein API KEY braucht.(auf der Websitestand das, von OpenweaterMap). Wie setzt man das jetzt in Python um, das man dann angemeldet ist oder so?
__deets__
User
Beiträge: 14525
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hast du dir die API-Dokumentation zu openweathermap angeschaut?

https://openweathermap.org/api
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Ja habe ich. Leider verstehe ich immer noch nicht wie ich den API Key einbauen muss.
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Hast Du den ziemlich eindeutig benannten Abschnitt Example of using API key in API call nicht gefunden?
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Doch jetzt wo du es sagst, habe ich mir den nochmal durchgelesen. Allerdings habe ich jetzt eine fertige lib gefunden. pyowm
und geojson. Das auslesen hat damit auch bestens geklappt. Jetzt wollte ich dass das ganze in einem Label im GUI angezeigt wird. Und das quasi jede Minute aktualiesiert wird. Leider klappt das so, wie ich es mir dachte nicht. Findet jmd da meinen Fehler?

Code: Alles auswählen

def Wetter(  ):
    global zeita
    global status   
    neuezeita = time.strftime('%M')
    if neuezeita != zeita:
            zeita = neuezeita
            w = observation.get_weather()
            Wind = w.get_wind()                  
             Temp = w.get_temperature('celsius')  
            stat = w.get_status()
            Status_Label.config(text="Es ist jetzt gerade " +str(status))
            Temperatur.config(text=str(Temp.get("temp"))+ "° sind es jetzt draußen")
            Temperatur_max.config(text="maximal" + str(Temp.get("temp_max")) + "° heute")
            Temperatur_min.config(text="minimal" + str(Temp.get("temp_min"))+ "°")



    fenster.after(200, Wetter) 
 
Wetter()

LG
Benutzeravatar
__blackjack__
User
Beiträge: 13077
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@No17: `Wetter` ist weder von der Schreibweise (alles ausser Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase) schreibt man in Python klein_mit_unterstrichen) noch vom Namen selbst eine Funktion. Funktionsnamen beschreiben in aller Regel die Tätigkeit, welche die Funktion ausführt. `Wetter` ist keine Tätigkeit. Zudem hat ``global`` nichts in einem Programm zu suchen und Funktionen und Methoden sollten alle Werte (ausser Konstanten) als Argument(e) übergeben bekommen und nicht ”magisch” aus der Umgebung bekommen.

Für nicht-triviale GUI-Programme kommt man um objektorientierte Programmierung (OOP) nicht herum.

Namen(steile) sollten nicht aus kryptischen Abkürzungen bestehen. Ein Name sollte dem Leser klar vermitteln was der Wert in dem Programm bedeutet.

Zeichenketten und Werte mit ``+`` und `str()` zusammenzustückeln ist eher BASIC als Python. In Python gibt es dafür Zeichenkettenformatierung mit der `format()`-Methode.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

OK verstehe dass das für ausßensetehende sehr blöd ist zu durchschauen. Ich werde mich normal dransetzen, das a) ordentlicher zu machen und b) vlt das problem gleich mitlösen. Vorher aber noch die Frage, gibt es einen "Maßstab" für OOP oder kannst du mir vlt für die falsch gemachten Fälle ein Musterbeispielcode geben, damit ich alles anpassen kann?

LG
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

in der offiziellen Python-Doku ist im Kapitel zu Tkinter ein Klassen-basierter Ansatz als Code gezeigt, der sich sehr gut als Ausgangspunkt für kleinere Projekte eignet.

Und bevor du das in eine GUI packst solltest du vielleicht erst mal testen, ob das im Terminal nach deinen Vorstellungen läuft. Und erst dann in eine GUI packen.

Gruß, noisefloor
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

No17 hat geschrieben: Sonntag 11. November 2018, 19:16 Leider klappt das so, wie ich es mir dachte nicht. Findet jmd da meinen Fehler?
Ist das hier ein Suchspiel? Was klappt micht so wie Du Dir das dachtest? Regnet es die ganze Zeit, obwohl die Anzeige auf sonnig steht? Gibt es eine Fehlermeldung? Wenn ja, welche?

Um das sauber umzusetzen, braucht die Funktion `aktualisiere_wetter` 7 Parameter, das sind einfach zu viele, ohne dass es unübersichtlich wird:

Code: Alles auswählen

def aktualisiere_wetter(aktuelle_zeit, observation, Status_Label, Temperatur, Temperatur_max, Temperatur_min):
    neue_zeit = time.strftime('%M')
    if neue_zeit != aktuelle_zeit:
            weather = observation.get_weather()
            temperature = weather.get_temperature('celsius')  
            status = weather.get_status()
            Status_Label.config(text="Es ist jetzt gerade {}".format(status))
            Temperatur.config(text="{}° sind es jetzt draußen".format(temperature.get("temp")))
            Temperatur_max.config(text="maximal {}° heute".format(temperature.get("temp_max")))
            Temperatur_min.config(text="minimal {}°".format(temperature.get("temp_min")))
    Status_Label.after(200, aktualisiere_wetter, neue_zeit, observation, Status_Label, Temperatur, Temperatur_max, Temperatur_min) 

def main():
    [...]
    aktualisiere_wetter("xx", observation, Status_Label, Temperatur, Temperatur_max, Temperatur_min)
    [...]
Dazu braucht man Klassen, die den Zustand kapseln.
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Im Terminal hat alles so geklappt wie ich mir erhofft habe.
Was klappt micht so wie Du Dir das dachtest? Regnet es die ganze Zeit, obwohl die Anzeige auf sonnig steht? Gibt es eine Fehlermeldung? Wenn ja, welche?
Nunja eine Fehlermeldung gibt es nicht. Das mit dem den ganzen Tag regnen trifft es schon ehr. Es ist so, dass sich die Temperatur... nicht aktualisiert, d.h es ist dauerhaft die gleiche Temperatur. Wenn ich alles neu starte, erst dann hat sich die Temperatur … auch wieder aktualisiert. Das ist das problem, welches noch gelöst werden muss, wie ich es schaffe das sich alles nach meinetwegen einer Minute neu aktualisiert.


@sirius3 Was hat der Code, den du gepostet hast für eine "bessere Funktion" bzw ist das bloß meiner in übersichtlicher Weise?
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Ohne das gesamte Programm zu kennen, kann man da wenig sagen.

Ich wollte nur zeigen, wie viele Parameter man braucht, weil die Funktion so viel Input braucht, dass es wenig Sinn macht, das ohne Klassen zu implementieren.
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

Nunja ich denke es macht wenig Sinn, das komplette Programm zu zeige ohne das ich vorher mal die "offensichtlichen" Fehler ausgemerzt habe. Wie gesagt, ich versuche das ganze nochmal neu zu machen mit dem OOP und diesen Klssen etc. Wenn jemand noch gute Tutorials dazu kennt, die man nicht direkt bei Google findet, dann ruhig her damit :-)
No17
User
Beiträge: 16
Registriert: Mittwoch 24. Oktober 2018, 14:40

so ich habe mal ein bissel rumgebastelt

Code: Alles auswählen

class wetter_vorhersage:
    def __init__(self, temperatur, wind):
        self.aktuelle_temperatur = temperatur
        self.maximale_temperatur = temperatur
        self.minimale_temperatur = temperatur
        self.windgeschwindigkeit = wind
        self.windrichtung = wind
        print("erstellt")
    def print(self):
        print("Temperatur aktuell {}".format(self.aktuelle_temperatur.get("temp")))
        print("maximal {}".format(self.maximale_temperatur.get("temp_max")))
        print("minimal {}".format(self.minimale_temperatur.get("temp_min")))
        print("Wind {}" .format(self.windgeschwindigkeit.get("speed")))
        print("Windrichtung {}".format(self.windrichtung.get("deg")))
        
        
        
vorhersage = wetter_vorhersage(w.get_temperature("celsius"), w.get_wind())
vorhersage.print()
so siehts jetzt aus. Kann mal jemdand sagen, ob das so erstmal ordentlich ist, bevor ich weiter mache.

LG
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Da temperatur ein Objekt zu sein schient, dass sowohl die aktuelle als auch max und min Temperaturen enthält, macht es wenig Sinn, das selbe Objekt in aktuelle_tempertur, maximale_temperatur und minimale_temperatur zu speichern. Das gleiche gilt für den Wind.
Klassen schreibt man GrossKlein: WetterVorhersage.
Insgesamt macht die Klasse keinen Sinn, wenn sie nur aus einer Methode besteht. Das könnte man auch als einfache Funktion schreiben.

Code: Alles auswählen

def print_wetter(temperatur, wind):
    print("Temperatur aktuell {}".format(temperatur.get("temp")))
    print("maximal {}".format(temperatur.get("temp_max")))
    print("minimal {}".format(temperatur.get("temp_min")))
    print("Wind {}" .format(wind.get("speed")))
    print("Windrichtung {}".format(wind.get("deg")))
oder falls man nur ein Argument möchte:

Code: Alles auswählen

def print_wetter(wetter, einheit="celsius"):
    temperatur = wetter.get_temperature(einheit)
    wind = wetter.w.get_wind()
    print("Temperatur aktuell {}".format(temperatur.get("temp")))
    print("maximal {}".format(temperatur.get("temp_max")))
    print("minimal {}".format(temperatur.get("temp_min")))
    print("Wind {}" .format(wind.get("speed")))
    print("Windrichtung {}".format(wind.get("deg")))
Antworten