OpenWeatherMap - Fehler bei Datenabfrage (KeyError)

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.
Antworten
MergedEyes
User
Beiträge: 6
Registriert: Freitag 14. August 2020, 15:12

Guten Tag liebes Forum,

ich bin gerade dabei eine Wettervorhersage mit der OpenWeatherMap API zu basteln. Dazu habe ich mir dieses YouTube Tutorial angesehen: https://www.youtube.com/watch?v=PWZKTWJ9bJE
Ich habe alle Schritte befolgt (und ein paar Anpassungen vorgenommen, was die bestimmten Daten angeht), wie sie im Video zu sehen sind.

Leider funktioniert das Auslesen der Daten der request nicht.
Ich erhalte immer diese Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "weather_api.py", line 12, in <module>
    city_name = data['name']
KeyError: 'name'

Mein Quellcode sieht, bis jetzt, folgendermaßen aus:

Code: Alles auswählen

import requests
from pprint import pprint

city = input('Geben Sie ihren Standort ein: ')

url = 'https://api.openweathermap.org/data/2.5/find?q={}&units=metric&appid=XXXX'.format(city)

res = requests.get(url)

data = res.json()

city_name = data['name']
country = data['sys']['country']
coord_lat = data['coord']['lat']
coord_lon = data['coord']['lon']
temp = data['main']['temp']
feels_like = data['main']['feels_like']
temp_min = data['main']['temp_min']
temp_max = data['main']['temp_max']
humidity = data['main']['humidity']
weather = data['weather']['description']
wind_speed = data['wind']['speed']
wind_deg = data['wind']['deg']

print(city_name ,country)
print(coord_lat , coord_lon)
print('Temperatur: ',temp)
print('Gefühlte Temperatur: ',feels_like)
Wenn ich die einzelnen Abfragen, wie z.B. city_name, deaktiviere und mir nur data Printen lasse (über pprint(data)) funktioniert es reibungslos und mir wird alles so angezeigt:

Code: Alles auswählen

mergedeyes@Jans-MacBook-Pro Weather_API % python weather_api.py
Geben Sie ihren Standort ein: Künzelsau
{'cod': '200',
 'count': 1,
 'list': [{'clouds': {'all': 40},
           'coord': {'lat': XX, 'lon': XX.6889},
           'dt': 1597414349,
           'id': 2882439,
           'main': {'feels_like': 24.78,
                    'humidity': 78,
                    'pressure': 1015,
                    'temp': 23.03,
                    'temp_max': 25,
                    'temp_min': 22},
           'name': 'Künzelsau',
           'rain': {'1h': 2.54},
           'snow': None,
           'sys': {'country': 'DE'},
           'weather': [{'description': 'moderate rain',
                        'icon': '10d',
                        'id': 501,
                        'main': 'Rain'}],
           'wind': {'deg': 210, 'speed': 2.1}}],
 'message': 'accurate'}
mergedeyes@Jans-MacBook-Pro Weather_API % 
Ich habe bereits den ganzen Tag gestern und heute recherchiert und habe leider keine Lösung für mein Problem gefunden. (Entweder bin ich blind und habe die entsprechenden Foren übersehen, oder ich bin der Einzige mit dem Problem :roll: )

Ich wäre verdammt dankbar, wenn mir jemand helfen könnte.

Liebe Grüße


Anmerkung: Ich habe erst vorgestern Abend mit Python angefangen, kenne mich also kaum aus. Nehmt es mir daher nicht übel, wenn ich "dumme" Fragen stelle, oder den vielleicht offensichtlichen Fehler nicht erkenne. Danke :-)
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Schau doch mal, wie `data` aufgebaut ist. Wo kommt in dieser Datenstruktur 'name' vor?
Es gibt einen `list`-Key, der wie der Name sagt, eine Liste ist und darin sind wiederum Wörterbücher (oder hier nur eins), das dann Deine gewünschten Daten enthält.
MergedEyes
User
Beiträge: 6
Registriert: Freitag 14. August 2020, 15:12

data sieht wie folgt aus:

Code: Alles auswählen

{
   "message":"accurate",
   "cod":"200",
   "count":1,
   "list":[
      {
         "id":2882439,
         "name":"Künzelsau",
         "coord":{
            "lat":49.2819,
            "lon":9.6889
         },
         "main":{
            "temp":23,
            "feels_like":24.33,
            "temp_min":23,
            "temp_max":23,
            "pressure":1015,
            "humidity":69
         },
         "dt":1597421540,
         "wind":{
            "speed":1.5,
            "deg":260
         },
         "sys":{
            "country":"DE"
         },
         "rain":{
            "1h":0.13
         },
         "snow":null,
         "clouds":{
            "all":20
         },
         "weather":[
            {
               "id":500,
               "main":"Rain",
               "description":"light rain",
               "icon":"10d"
            }
         ]
      }
   ]
}
Ok, jetzt habe ich schon mal verstanden, was es mit list auf sich hat. Wie komme ich nun in die Liste und dann zum Key "name"?

Wenn ich den Code so abändere:

Code: Alles auswählen

city_name = data['list']['name']
wird mir vom Terminal folgende Fehlermeldung ausgespuckt:

Code: Alles auswählen

Traceback (most recent call last):
  File "weather_api.py", line 13, in <module>
    city_name = data['list']['name']
TypeError: list indices must be integers or slices, not str
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

data['list'] ist eine Liste und wie man auf eine Liste zugreift, sollte in Deinem Anfängertutorial beschrieben sein.
MergedEyes
User
Beiträge: 6
Registriert: Freitag 14. August 2020, 15:12

Sirius3 hat geschrieben: Freitag 14. August 2020, 17:55 data['list'] ist eine Liste und wie man auf eine Liste zugreift, sollte in Deinem Anfängertutorial beschrieben sein.
Ah, ich habe jetzt ein anderes Tut gefunden indem es verständlicher erklärt wird (https://www.youtube.com/watch?v=oQfNYqz8pLs).
Für mich war das leider total unverständlich, was der Herr im ersten Tutorial gemacht hat.

Jetzt kann ich auf die Liste zugreifen und bin auch soweit, dass ich den Namen auslesen kann. Habe ich das richtig verstanden, dass jede { ... } n neues dict ist und innerhalb dieses dicts sind dann wiederum Keys mit Values?
Man fängt ja bei 0 an mit zählen, richtig?
Jetzt habe ich das Problem, dass bei dem Auslesen des Landes der Index out of range sei.
Hier der dazugehörige Code:

Code: Alles auswählen

country = data['list'][4]['country']
Laut json Datei müsste aber 'country' beim index 4 sein oder?

Code: Alles auswählen

"list":[
      {
         "id":2882439,
         "name":"Künzelsau",
         "coord":{
            "lat":49.2819,
            "lon":9.6889
         },
         "main":{
            "temp":23,
            "feels_like":24.33,
            "temp_min":23,
            "temp_max":23,
            "pressure":1015,
            "humidity":69
         },
         "dt":1597421540,
         "wind":{
            "speed":1.5,
            "deg":260
         },
         "sys":{
            "country":"DE"
         }
MergedEyes
User
Beiträge: 6
Registriert: Freitag 14. August 2020, 15:12

Habe da Problem gefunden. Index immer 0 und ab da weiter mit z.B. ['sys']['country'].
MergedEyes
User
Beiträge: 6
Registriert: Freitag 14. August 2020, 15:12

Also habe es nun hinbekommen. :-) Danke für deine Unterstützung Sirius3.

Mein Code sieht jetzt final so aus:

Code: Alles auswählen

import requests

city = input('Geben Sie ihren Standort ein: ')

url = 'https://api.openweathermap.org/data/2.5/find?q={}&units=metric&appid=XXXX'.format(city)

res = requests.get(url)

data = res.json()

city_name = data['list'][0]['name']
country = data['list'][0]['sys']['country']
coord_lat = data['list'][0]['coord']['lat']
coord_lon = data['list'][0]['coord']['lon']
temp = data['list'][0]['main']['temp']
feels_like = data['list'][0]['main']['feels_like']
temp_min = data['list'][0]['main']['temp_min']
temp_max = data['list'][0]['main']['temp_max']
humidity = data['list'][0]['main']['humidity']
weather = data['list'][0]['weather'][0]['description']
wind_speed = data['list'][0]['wind']['speed']
wind_deg = data['list'][0]['wind']['deg']

print(city_name ,', ',country)
print(coord_lat ,', ',coord_lon)
print('Wetter: ',weather)
print('Temperatur in Grad Celsius: ',temp)
print('Gefühlte Temperatur in Grad Celsius: ',feels_like)
print('Niedrigste Temperatur in Grad Celsius: ',temp_min)
print('Höchste Temperatur in Grad Celsius: ',temp_max)
print('Luftfeuchtigkeit in %: ',humidity)
print('Windgeschwindigkeit in km/h: ',wind_speed)
print('Windrichtung in Grad: ',wind_deg)

Und das ist der Output:

Code: Alles auswählen

mergedeyes@Jans-MacBook-Pro Weather_API % python weather_api.py
Geben Sie ihren Standort ein: Künzelsau
Künzelsau ,  DE
Xx.2819 ,  XX.6889
Wetter:  few clouds
Temperatur in Grad Celsius:  23.48
Gefühlte Temperatur in Grad Celsius:  25.73
Niedrigste Temperatur in Grad Celsius:  23
Höchste Temperatur in Grad Celsius:  24
Luftfeuchtigkeit in %:  73
Windgeschwindigkeit in km/h:  1
Windrichtung in Grad:  290
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@MergedEyes: du veröffentlichst hier sowohl geheime API keys als auch sehr gut persönlich identifizierbare Informationen. Das solltest du nicht tun. Ich habe die mal nach bestem Wissen & gewissen redigiert, aber bitte in Zukunft selbst drauf achten. Oder mit Konsequenzen rechnen.
MergedEyes
User
Beiträge: 6
Registriert: Freitag 14. August 2020, 15:12

__deets__ hat geschrieben: Freitag 14. August 2020, 18:34 @MergedEyes: du veröffentlichst hier sowohl geheime API keys als auch sehr gut persönlich identifizierbare Informationen. Das solltest du nicht tun. Ich habe die mal nach bestem Wissen & gewissen redigiert, aber bitte in Zukunft selbst drauf achten. Oder mit Konsequenzen rechnen.
Stimmt, das hätte ich nicht machen sollen. Ich pass beim nächsten Mal auf, danke!
Antworten