web-dev-qa-db-fra.com

TypeError: les indices de chaîne doivent être des entiers lors de l'analyse JSON à l'aide de Python?

Je ne comprends pas pourquoi je ne suis pas en mesure d'analyser cette chaîne JSON. Un code similaire fonctionne très bien sur une autre chaîne JSON mais pas sur celle-ci - j'essaie d'analyser la chaîne JSON et d'extraire le script du JSON.

Voici mon code.

for step in steps:
    step_path = '/example/v1' +'/'+step

    data, stat = zk.get(step_path)
    jsonStr = data.decode("utf-8")
    print(jsonStr)
    j = json.loads(json.dumps(jsonStr))
    print(j)
    Shell_script = j['script']
    print(Shell_script)

Ainsi, la première print(jsonStr) imprimera quelque chose comme ça -

{"script":"#!/bin/bash\necho Hello world1\n"}

Et la deuxième print(j) imprimera quelque chose comme ça -

{"script":"#!/bin/bash\necho Hello world1\n"}

Et puis la troisième impression n'est pas imprimée et cela donne cette erreur -

Traceback (most recent call last):
  File "test5.py", line 33, in <module>
    Shell_script = j['script']
TypeError: string indices must be integers

Je me demande donc quel mal je fais ici?

J'ai utilisé le même code ci-dessus pour analyser le JSON et cela fonctionne bien ..

19
AKIWEB

Essayez de remplacer j = json.loads(json.dumps(jsonStr)) par j = json.loads(jsonStr).

19
1st1

Le problème est que jsonStr est une chaîne qui code un objet en JSON, pas l'objet réel.

Vous évidemment saviez c'était une chaîne, parce que vous l'appeliez jsonStr. Et cela est prouvé par le fait que cette ligne fonctionne:

jsonStr = data.decode("utf-8")

Ainsi, jsonStr est une chaîne. Appeler json.dumps sur une chaîne est parfaitement légal. Peu importe que cette chaîne soit l'encodage JSON d'un objet ou votre nom de famille; vous pouvez encoder cette chaîne en JSON. Et puis vous pouvez décoder cette chaîne, récupérer la chaîne d'origine.

Donc ça:

j = json.loads(json.dumps(jsonStr))

… Va vous rendre exactement la même chaîne que jsonStr dans j. Ce que vous n'avez toujours pas décodé vers l'objet d'origine.

Pour ce faire, ne faites pas l'encodage supplémentaire:

j = json.loads(jsonStr)

Si ce n'est pas clair, essayez de jouer avec lui sur un terminal interactif:

>>> obj = ['abc', {'a': 1, 'b': 2}]
>>> type(obj)
list
>>> obj[1]['b']
2
>>> j = json.dumps(obj)
>>> type(j)
str
>>> j[1]['b']
TypeError: string indices must be integers
>>> jj = json.dumps(j)
>>> type(jj)
str
>>> j
'["abc", {"a": 1, "b": 2}]'
>>> jj
'"[\\"abc\\", {\\"a\\": 1, \\"b\\": 2}]"'
>>> json.loads(j)
['abc', {'a': 1, 'b': 2}]
>>> json.loads(j) == obj
True
>>> json.loads(jj)
'["abc", {"a": 1, "b": 2}]'
>>> json.loads(jj) == j
True
>>> json.loads(jj) == obj
False
31
abarnert