json aus request richtig auslesen?

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
crlin
User
Beiträge: 4
Registriert: Montag 2. Mai 2016, 10:56

Hallo zusammen,

ich habe ein Problem beim Auslesen einer JSON Datei, die ich per requests einlese. Das Script sieht (vereinfacht) folgendermaßen aus
import requests
import json

url = 'http://www.myurl.de/?bla'
userResponse = requests.request("GET", url, headers=userHeaders)

userJson = json.loads(userResponse.content)

# alles ausgeben
print(userJson)
# 1. unterklasse
print(userJson[u'kat1']
# 2. unterklasse
print(userJson[u'kat1'][u'unterkat1']

# 3. unterklasse ausgeben: funktioniert nicht!
print(userJson[u'kat1'[u'unterkat1'][u'unterunterkat']
Zur Erklärung: alle Infos der JSON Datei befinden sich unter kat1; es gibt mehrere Unterkategorien, wovon unterkat1 eben eine ist. Innerhalb von unterkat1 befinden sich sehr viele Werte. Ich möchte aber lediglich alle Werte von unterunterkat ausgeben (bzw. eigentlich als array speichern).

Die eingelesene JSON Datei hat eine valide Struktur; das Ausgeben der gewünschten Werte funktioniert jedoch nicht. Was mache ich falsch bzw. wie kann ich das Problem lösen?

Die Fehlermeldung bei 3. lautet
print(jsonResponse[u'kat1'][u'unterkat1'][u'unterunterkat'])
TypeError: list indices must be integers, not unicode
Damit kann ich allerdings nichts anfangen :/ könnt Ihr mir auf die Sprünge helfen? Ich habe schon versucht, die Ausgabe von unicode in integers umzuwandeln, das aber auch ohne Erfolg...

Danke!
BlackJack

@crlin: Das JSON hat offensichtlich nicht die Struktur die Du annimmst. Unter 'kat1' und 'unterkat1' ist kein weiteres Wörterbuch sondern der Meldung nach eine Liste.

Die Antwort von `requests.request()` hat übrigens ein JSON-Attribut/eine JSON-Methode. Da musst Du nichts selber parsen. Und statt `request()` würde ich `get()` verwenden wenn es für `request()` keinen besonderen Grund gibt.
crlin
User
Beiträge: 4
Registriert: Montag 2. Mai 2016, 10:56

@BlackJack: danke für die Infos. Ich hätte noch anmerken sollen, dass ich ein absoluter Anfänger auf dem Gebiet Python bin :oops:

Das json Attribut hatte ich in einer früheren Version meines Codes sogar drin. Mit

Code: Alles auswählen

userJson = userResponse.json
funktioniert die Ausgabe. kat1 und unterkat1 kann ich entsprechend direkt dort mit einbinden.
Und statt `request()` würde ich `get()` verwenden wenn es für `request()` keinen besonderen Grund gibt.
Also nach diesem Schema:

Code: Alles auswählen

userResponse = r.get(url, headers=userHeaders)
Auch das hatte ich in einer älteren Version meines Codes genommen. Ich arbeite mit Postman, welches mir Python-Vorlagen in dem Format ausgibt, die ich im ersten Posting angegeben habe. Daher bin ich gleich dabei geblieben...
kein weiteres Wörterbuch sondern der Meldung nach eine Liste.
Ich schaffe es dennoch nicht, lediglich die ID Werte des Wörterbuches auszugeben... Die Struktur der JSON Datei sieht folgendermaßen aus

Code: Alles auswählen

{"kat1": {
    "seite": 1,
    "proseite": 99,
    "gesamt": 613,
    "count": 99,
    "unterkat1": [
      {
        "sollAusgegebenWerden": "dieser wert",
        "wert2": "hi",
        "wert3": "wo",
        "unterkat2": [
          "bli",
          "bla",
          "blubb",
        ],
        "wert4": {},
        "wert5": 888,
        "wert6": 10,
      },
      {
        "sollAusgegebenWerden": "dieser wert",
        "wert2": "hi",
        "wert3": "wo",
        "unterkat2": [
          "bli",
          "bla",
          "blubb",
        ],
        "wert4": {},
        "wert5": 888,
        "wert6": 10,
      },
      {
        "sollAusgegebenWerden": "und dann noch dieser",
        "wert2": "hi",
        "wert3": "wo",
        "unterkat2": [
          "bli",
          "bla",
          "blubb",
        ],
        "wert4": {},
        "wert5": 888,
        "wert6": 10,
      },
Im Idealfall kann ich jetzt aus allen Werten von "sollAusgegebenWerden" eine neue Liste (oder besser dict?) erstellen, die ich dann ausgeben bzw. weiterverarbeiten kann...
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@crlin: wie BlackJack schon geschrieben hat, ist unterkat1 eine Liste von Wörterbüchern. Und warum das eine Liste ist, sollte eigentlich klar werden aus der Art der Daten, die Du da abfragst. Und wie man die Daten weiterverarbeitet, sollte aus Deiner Aufgabenstellung klar werden:

Code: Alles auswählen

sollAusgegebenWerden = [w['sollAusgegebenWerden'] for w in userJson['kat1']['unterkat1']]
crlin
User
Beiträge: 4
Registriert: Montag 2. Mai 2016, 10:56

Danke! So hat es geklappt.
umsid
User
Beiträge: 9
Registriert: Sonntag 6. September 2015, 09:36

Hallo Leute,

vielleicht stelle ich mich noch viel blöder an, aber ich hänge an einer ähnlichen Stelle:

Vorab: Ich bin blutiger Anfänger mit Python.

Ich habe folgendes versucht:

Code: Alles auswählen

 
Webseite = "http://www.ipsc-dvc.org/components/com_ipsc/JsonMasterScoreReadMatchList.php?status=matchlist&shid="+aReturn[0]+"&ver="+aReturn[2]

t = urllib.request.urlopen(Webseite)

tempMatchList = t.read()
    
MatchList = json.loads(tempMatchList.decode(encoding='UTF-8'))
    
# und ausgeben
print(MatchList)
Soweit funktionier das auch, das Print(Matchlist) liefert das gewünschte Ergebnis:

Code: Alles auswählen

[{'date': '2016-05-26', 'KindOfMatch': '0', 'name': 'IPSC Helmbrechts Cup 2016', 'id': '659'}, {'date': '2016-07-09', 'KindOfMatch': '0', 'name': 'MOS Summer', 'id': '639'}, {'date': '2016-07-29', 'KindOfMatch': '0', 'name': '11. Güstrow-Open', 'id': '677'}, {'date': '2016-09-17', 'KindOfMatch': '0', 'name': 'MOS Autumn', 'id': '638'}, {'date': '2016-11-04', 'KindOfMatch': '0', 'name': 'MOS Winter', 'id': '637'}]
Mein Problem ist:
Wie komme ich jetzt weiter, wie kann ich die einzelnen "Datensätze" in ein Array oder in eine Liste einlesen?

Vorab schon vielen Dank für Eure Hilfe
Guenter
BlackJack

@umsid: Du hast da doch bereits einzelne Datensätze in einer Liste. Wenn Du wissen willst wie man mit Listen und Wörterbüchern umgeht, solltest Du Python lernen. Das sind *die* beiden Grundcontainertypen von Python, die werden in jedem Einsteigertutorial behandelt. So auch im Tutorial in der Python-Dokumentation.

Beim kennenlernen und experimentieren hilft auch eine interaktive Python-Shell weiter. Da kann man sich die Daten ”live” anschauen und auseinandernehmen, und ausprobieren was welche Operation als Ergebnis liefert.
umsid
User
Beiträge: 9
Registriert: Sonntag 6. September 2015, 09:36

Hallo Black Jack,

vielen Dank für die schnelle Antwort.
Es funktioniert - und: ich werde mich in die Listen und Wörterbücher Geschichte einlesen.

Hab mal ganz schnell in meinen Source ein paar Zeilen eingefügt und bekomme jetzt die Listenelemente einzeln.
Wenn ich das richtig sehe, ist jetzt EIN Listenelement vom Typ Wörterbuch. Aber das kann ich erst heute abend oder morgen mal testen. Muss um 17:30 weg - muss noch einiges vorbereiten.

Was verstehst Du unter "Interaktive Python Shell"?
Ist das die "ganz normale Shell vom 3.5.1?

Vielen Dank nochmal und viele Grüße
Guenter
BlackJack

@umsid: Interaktive Python-Shell ist alles wo man Python-Anweisungen eingeben kann die dann sofort ausgeführt werden. Also die, die man bekommt wenn man einfach nur Python auf einer Konsole startet, oder das erste Fenster bei IDLE, oder auch Alternativen wie IPython oder BPython.
Antworten