Filtrage JSON avec Python
Fermé
Lynow
-
Modifié le 29 juin 2022 à 11:02
mamiemando Messages postés 33410 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 décembre 2024 - 30 juin 2022 à 12:36
mamiemando Messages postés 33410 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 2 décembre 2024 - 30 juin 2022 à 12:36
A voir également:
- Filtrage JSON avec Python
- Citizen code python avis - Accueil - Outils
- Python est introuvable. exúcutez sans argument pour procúder ó l ✓ - Forum Python
- Trouver la position d'un élément dans une liste python ✓ - Forum Python
- [PyCharm] Pas d'interpréteur python ✓ - Forum Python
3 réponses
mamiemando
Messages postés
33410
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
2 décembre 2024
7 808
29 juin 2022 à 11:21
29 juin 2022 à 11:21
Bonjour,
On ne peut pas reproduire ton problème avec le code partagé (l'URL de l'API est offusquée). S'il s'agit d'une API publique, tu peux l'indiquer et on pourra tester ton script.
Autrement, il faudrait joindre un exemple de json que tu obtiens. S'il est bien formé tu devrais pouvoir utiliser
Bonne chance
On ne peut pas reproduire ton problème avec le code partagé (l'URL de l'API est offusquée). S'il s'agit d'une API publique, tu peux l'indiquer et on pourra tester ton script.
Autrement, il faudrait joindre un exemple de json que tu obtiens. S'il est bien formé tu devrais pouvoir utiliser
json.loads.
Bonne chance
mamiemando
Messages postés
33410
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
2 décembre 2024
7 808
Modifié le 29 juin 2022 à 15:32
Modifié le 29 juin 2022 à 15:32
Bonjour,
Je ne vois pas trop l'intérêt de transformer ton dictionnaire sous forme de liste, mais pourquoi pas :-)
En tout cas, l'opérateur
Le message d'erreur
Maintenant regardons ce que tu as écrit :
Il y beaucoup de choses qui ne vont pas :
Il serait donc plus naturel d'écrire :
... ou plus simplement :
... ou encore plus simple :
... ou pour plus de lisibilité :
Bonne chance
Je ne vois pas trop l'intérêt de transformer ton dictionnaire sous forme de liste, mais pourquoi pas :-)
En tout cas, l'opérateur
[]n'a pas le même sens selon que tu l'appliques à une liste ou un dictionnaire :
- pour une liste, il faut passer un entier (entre 0 et la longueur de la liste - 1) qui indique quel élément on prend ;
- pour un dictionnaire, il faut passer la clé (un type hashable, dans ton cas de sont des chaînes de caractères) qui indique quel valeur on récupère.
- sans variable à sa gauche, il permet de créer une liste à la volée (e.g.,
[1, 2, 3]
)
Le message d'erreur
TypeError: list indices must be integers, not strsignifie que tu as passé une chaîne de caractère (au lieu d'un index) à un opérateur
[]appliqué à une liste.
Maintenant regardons ce que tu as écrit :
["response"]["Attribute"][i-1]signifie :
- crée une liste contenant la chaîne
"response"
; - récupère dans cette liste l'élément identifié par la clé
"Attribute"
(ça n'a pas de sens, puisqu'il faudrait passé un index, ici forcément0
puisque ta liste n'a qu'un élément) - dans l'objet retourné (que ton code espère de type liste), récupère l'élément
i - 1
.
Il y beaucoup de choses qui ne vont pas :
- tout d'abord, si je reprends mes notations, tu veux probablement plutôt écrire
reponse["response"]["Attribute"][i-1]
(et dans ce cas, reponse étant un dictionnaire, la suite à plus de sens) - ensuite tu veux récupérer l'élément
i-1
, or dans ta bouclefor i in range(nombre_attribut)
, la première valeur prise pari
sera-1
(pour rappel, le premier élément d'une liste est à l'index0
). Le programme marcherait car en python, l'élément-k
signifie prend le k-ième élement en partant de la fin, donc ça ferait ce qu'il faut, mais ce n'est sans doute pas ce que tu voulais écrire.
Il serait donc plus naturel d'écrire :
liste = reponse["response"]["Attribute"] for i in range(len(liste)): print(list[i])
... ou plus simplement :
liste = reponse["response"]["Attribute"] for element in liste: print(element)
... ou encore plus simple :
liste = reponse["response"]["Attribute"] print(liste)
... ou pour plus de lisibilité :
from pprint import pprint liste = reponse["response"]["Attribute"] pprint(liste)
Bonne chance
Merci pour ces explications, j'avais corrigé mon erreur plus haut en éditant mon message, mais cela devient d'autant plus clair avec ton message.
J'ai modifié mon script et m'occupe maintenant uniquement des évènements et non pas des attributs (pour une raison interne à l'outil).
A savoir que maintenant je considère que "reponse" contient plusieurs évènements.
Voici mon code actuel :
D'après mon print ligne 50, j'ai bien tous les ids qui sont dans la liste. Pourtant, aucun tag n'est ajouté après vérification sur l'outil web.
J'ai donc remplacé cette ligne :
Et cela fonctionne ! Je ne comprends pas
J'ai modifié mon script et m'occupe maintenant uniquement des évènements et non pas des attributs (pour une raison interne à l'outil).
A savoir que maintenant je considère que "reponse" contient plusieurs évènements.
Voici mon code actuel :
import requests from requests.structures import CaseInsensitiveDict import json import re ################################# ### APPEL API ### url = "https://xxxx.xxxx.xxxx.xxxx/events/index" headers = CaseInsensitiveDict() headers["Authorization"]="xxxxxxxxxxxxxxxxxxxxxxx" headers["Accept"] = "application/json" headers["Content-Type"] = "application/json" data = '{"event_timestamp":"20d"}' requete = requests.post(url, headers=headers, data=data, verify=False) ### ### Recuperation au format json et en tant qu'object python ### reponse = requete.json() ### ### Recuperation des IDs events ### nombre_attribut = (len(reponse)) liste=[] for i in range(nombre_attribut): obj = reponse[i] liste.append(obj["id"]) nombre_id = len(liste) ### ### Ajout des tags aux events concernes ### for j in range(nombre_id): url = "https://xxxx.xxxx.xxxx.xxxx/events/addTag" headers = CaseInsensitiveDict() headers["Authorization"]="xxxxxxxxxxxxxxxxxxxxxxxxx" headers["Accept"] = "application/json" headers["Content-Type"] = "application/json" data = '{"id":liste[j],"tag":"Test"}' print(liste[j]) requete = requests.post(url, headers=headers, data=data, verify=False)
D'après mon print ligne 50, j'ai bien tous les ids qui sont dans la liste. Pourtant, aucun tag n'est ajouté après vérification sur l'outil web.
J'ai donc remplacé cette ligne :
data = '{"id":liste[j],"tag":"Test"}'en mettant par exemple :
data = '{"id":1489,"tag":"Test"}', ou encore :
data = '{"id":1490,"tag":"Test"}'
Et cela fonctionne ! Je ne comprends pas
mamiemando
Messages postés
33410
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
2 décembre 2024
7 808
Modifié le 30 juin 2022 à 12:36
Modifié le 30 juin 2022 à 12:36
Bonjour
#7
Si tu écris :
... alors
... et ensuite rien ne t'empêche de faire :
#9
À mon avis tu devrais distinguer dans le nommage data (la structure de donnée python) et la chaîne de caractère JSON qui lui correspond (tu peux l'appeler
Bonne chance
#7
Si tu écris :
data = '{"id":liste[j],"tag":"Test"}'
... alors
dataest une chaîne (ce n'est même pas du JSON à cause de liste[j]) et donc tu perds les bénéfices apportés par une structure python (en l'occurrence un dictionnaire). Donc il faudrait plutôt écrire
data = {"id":liste[j],"tag":"Test"}
... et ensuite rien ne t'empêche de faire :
print(json.dumps(data))
#9
À mon avis tu devrais distinguer dans le nommage data (la structure de donnée python) et la chaîne de caractère JSON qui lui correspond (tu peux l'appeler
s_jsonpar exemple).
Bonne chance
29 juin 2022 à 11:42
En effet je ne peux pas donner accès à l'AIP, voici donc un exemple de réponse que je peux avoir après le code :
Modifié le 29 juin 2022 à 11:54
Exemple :
Bonne chance
Modifié le 29 juin 2022 à 15:20
Cela a l'air de fonctionner. Ensuite pour parcourir le json j'ai pensé à ceci :
Je récupère le nombre d'attributs du JSON pour ensuite faire une boucle for afin d'ajouter chaque ids dans une nouvelle liste (je n'ai pas encore écrit cette nouvelle liste).