Python JSON öffnen - Bitte um Hilfe

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
wagnerbua
User
Beiträge: 6
Registriert: Samstag 2. März 2019, 18:59

Hallo Liebe Community,

ich hab ein Problem und leider noch nirgends eine Lösung gefunden. Vielleicht habe ich auch nicht "richtig" gesucht aber ich weiß nicht was der Fehler ist und tu mir so mit dem Suchen schwer.

Ich habe einen Raspberry Pi mit Raspbian und python.

Ich möchte Feiertage die ich per JSON über eine API beziehe ausgeben und weiterverarbeiten.

Code: Alles auswählen

import urllib.request, json
with urllib.request.urlopen("https://xxxxxxx.xx/api/Data/GeoId/?api_key=xxxxxxxxxxxx") as url:
    data = json.loads(url.read().decode())

for event in data:
  print(event['description'])

Eigentlich sollte print die liste Feiertage ausgeben, leider kommt aber folgende Fehlermeldung:
Traceback (most recent call last):
File "getjson.py", line 6, in <module>
print(event['description'])
TypeError: string indices must be integers

Ich hab schon viel herumprobiert was man so in anderen Foren oder Seiten findet - bin aber nicht draufgekommen.

Bitte um Hilfe - Danke Martin

PS: Hier die JSON Daten:

Code: Alles auswählen

{
"interface":"XXXX",
"source":{"href":"https:\/\/XXXX.xx",
"description":"xxxx.xx"},
"copyright":{"href":"https:\/\/xxx.xx","description":"xxxxxxxxxx"},
"apiName":"Data\/GeoId",
"apiStatus":{"description":"active"},
"date":"02.03.19",
"request":{"geoId":"3126","year":"2019","class":"4","charset":"utf-8","format":"json","date_format":"d.m.y","hl":"de"},
"results":{"status":{"description":"ok"},
"location":{"description":"Nieder\u00f6sterreich",
"type":"Bundesland",
"geoId":"3126",
"iso":"AT",
"iso-3166-2":"AT-3",
"events":[
{"description":"Neujahr",                           "id":"1","dateStart":"01.01.19","dateEnd":"01.01.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Heilige drei K\u00f6nige",          "id":"4","dateStart":"06.01.19","dateEnd":"06.01.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Ostern",                            "id":"18","dateStart":"21.04.19","dateEnd":"21.04.19","class":"4","percent":"100","prov":"0","note":null},
{"description":"Ostermontag",                       "id":"19","dateStart":"22.04.19","dateEnd":"22.04.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Staatsfeiertag \u00d6sterreich",    "id":"75","dateStart":"01.05.19","dateEnd":"01.05.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Christi Himmelfahrt",               "id":"31","dateStart":"30.05.19","dateEnd":"30.05.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Pfingsten",                         "id":"30","dateStart":"09.06.19","dateEnd":"09.06.19","class":"4","percent":"100","prov":"0","note":null},
{"description":"Pfingstmontag",                     "id":"35","dateStart":"10.06.19","dateEnd":"10.06.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Fronleichnam",                      "id":"38","dateStart":"20.06.19","dateEnd":"20.06.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Mari\u00e4 Himmelfahrt",            "id":"42","dateStart":"15.08.19","dateEnd":"15.08.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Nationalfeiertag \u00d6sterreich",  "id":"74","dateStart":"26.10.19","dateEnd":"26.10.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Allerheiligen",                     "id":"47","dateStart":"01.11.19","dateEnd":"01.11.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Allerseelen",                       "id":"99","dateStart":"02.11.19","dateEnd":"02.11.19","class":"4","percent":"100","prov":"0","note":null},
{"description":"St. Leopold",                       "id":"103","dateStart":"15.11.19","dateEnd":"15.11.19","class":"4","percent":"100","prov":"0","note":null},
{"description":"Mari\u00e4 Empf\u00e4ngnis",        "id":"51","dateStart":"08.12.19","dateEnd":"08.12.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Christtag",                         "id":"23","dateStart":"25.12.19","dateEnd":"25.12.19","class":"1","percent":"100","prov":"0","note":null},
{"description":"Stefanitag",                        "id":"37","dateStart":"26.12.19","dateEnd":"26.12.19","class":"1","percent":"100","prov":"0","note":null}
]}}}
the life is leiwand :idea:
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du iterierst ueber das GESAMTE json-Objekt. Was bedeutet, dass du nacheinander die Schluessel zurueckbekommst. Was du auch leicht haettest selbst rausfinden koennen, indem du mal ein print(event) einstreust, bevor du damit weiter arbeitest.

Du musst auf data['events'] zugreifen, wenn du nur ueber die events laufen willst.
wagnerbua
User
Beiträge: 6
Registriert: Samstag 2. März 2019, 18:59

Hallo __deets__

Danke für Deine rasche Antwort:

Jetzt wo Du es sagst ich hab sogar einen teil auslesen können.

Code: Alles auswählen

import urllib.request, json
with urllib.request.urlopen("https://xxxx.xx/api/Data/GeoId/?api_key=xxxxx") as url:
    data = json.loads(url.read().decode())
    print (data['interface'])
hat mir den richtigen wert ausgegeben.

Code: Alles auswählen

import urllib.request, json
with urllib.request.urlopen("https://xxxx.xx/api/Data/GeoId/?api_key=xxxxx") as url:
    data = json.loads(url.read().decode())
    print (data['results'])
gibt mir auch alle ergebnisse aus!


Nur schaffe ich es nicht nur die description oder id oder sonst etwas von data['results'] auszulesen.

Ebenfalls kann ich nicht nur events auslesen
Traceback (most recent call last):
File "getjson.py", line 4, in <module>
print (data['events'])
KeyError: 'events'


Hast Du da noch einen tip für mich?

LG Martin
the life is leiwand :idea:
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja, immer wieder den gleichen: wenn ein Wert nicht deiner Erwartung entspricht, gib ihn dir aus bevor du ihn verwendest, damit du siehst, wie er wirklich aussieht.
wagnerbua
User
Beiträge: 6
Registriert: Samstag 2. März 2019, 18:59

__deets__ hat geschrieben: Sonntag 3. März 2019, 12:57 Ja, immer wieder den gleichen: wenn ein Wert nicht deiner Erwartung entspricht, gib ihn dir aus bevor du ihn verwendest, damit du siehst, wie er wirklich aussieht.
Das hilft jetzt nicht wirklich weiter!?!

Die Feiertage werden bei data['results'] ja alle ausgegeben ich weisss nur nicht wie ich z.b. nur dateStart ausgeben kann. (um das geht es mir konkret)

ich benötige die einzelnen Feiertage um diese mit dem aktuellen Datum zu vergleichen und dann ein relais an diesen tagen nicht zu schalten.

Ich bin Neuling und habe nichts dazu gefunden wie ich Details aus den gesamten "results" herausbekomme.

Bitte - Danke LG Martin
the life is leiwand :idea:
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

du musst dich eben durch die gesamte Datenstruktur hangeln. Wenn dein Ergebnis unterhalb des Schlüssels ‚results‘ steht, dann musst du den eben mit angeben.

print(data["results"]["nächster-Schlüssel"])

Und so weiter. Und doch, sich die Daten ausgeben zu lassen hilft.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Gib doch einfach mal 'print(data)' aus und vergleiche, ob die Datenstruktur dem entspricht, was Du glaubst, eingelesen zu haben.
wagnerbua
User
Beiträge: 6
Registriert: Samstag 2. März 2019, 18:59

Hallo Leute,

mit diesem Hinweis:
print(data["results"]["nächster-Schlüssel"])
habt Ihr mir schon sehr weit geholfen

Code: Alles auswählen

 print (data['results']['location']['events'])
Damit wird nur die Tabelle der Feiertage ausgegeben....

Aber warum funktioniert dieser print befehl dann nicht?:

Code: Alles auswählen

 print (data['results']['location']['events']['description'])
Fehler:
Traceback (most recent call last):
File "getjson.py", line 4, in <module>
print (data['results']['location']['events']['description'])
TypeError: list indices must be integers or slices, not str
Ist der Datensatz beschädigt oder irgend so etwas?
oder muss man in dem events[ ... dann irgend wie anders zugreifen?

Vielen Dank schon jetzt für eure hilfe!

LG Martin
the life is leiwand :idea:
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst wirklich die Grundlagen von Python Datenstrukturen lernen. Die beiden die hier eine Rolle spielen sind Woerterbuecher (dicts) und Listen (list). Schau dir mal an, was die Python-Dokumentation dazu zu sagen hat.

Und mal als kleine Denksportaufgabe: du hast da oben ~20 oder so Feiertage. Was waere denn deine Erwartung, was data['results']['location']['events']['description'] dir dann zurueck geben sollte?
wagnerbua
User
Beiträge: 6
Registriert: Samstag 2. März 2019, 18:59

Hallo __deets__

Ich werd mir mal dicts und list ansehen - danke für den Hinweis.
Das sind eben die Punkte wenn man komplett neu ist, dass man gar nicht weiß wo man nach dem Fehler suchen muss :-)

Ich hätte mir vorgestellt das data['results']['location']['events']['description']

Neujahr
Heilige drei Könige
Ostern
usw. ausgibt

Ich dachte wenn ich mir eine Liste der dateStart ausgebe

also eben
01.01.2019
06.01.2019
21.04.2019

das ich die Liste dann mit dem aktuellen Datum vergleichen kann und wenn es übereinstimmt dann soll er eben das Relais an dem Tag nicht schalten.

Bin für jeden weiteren Hinweis offen und dankbar!

LG Martin
the life is leiwand :idea:
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na du hast halt eine Liste. Es gibt keine Magie, die es dir erlaubt, Schluessel *in* der Liste wieder zu einer Liste von Werten zu machen. Sondern *das* ist eben zu programmieren.
wagnerbua
User
Beiträge: 6
Registriert: Samstag 2. März 2019, 18:59

Hallo __deets__

Jetzt hat mein Verständnis für das ganze einen riesen Sprung nach vorne gemacht :-P

Code: Alles auswählen

import urllib.request, json
with urllib.request.urlopen("https://xxxx.xx/api/Data/GeoId/?api_key=xxxxx") as url:
    data = json.loads(url.read().decode())
    event = data['results']['location']['events']
for datum in event:
        print(datum['dateStart'])
Jetzt hats so geklappt!

Für mein Gesamtprojekt ist es zwar erst ein kleiner Teil und ich befürchte das ich noch andere Fragen haben werde - aber fürs erste kann ich mal weiterprobieren :-)

Vielen Dank.

LG Martin
the life is leiwand :idea:
Antworten