web-dev-qa-db-fra.com

Comment vérifier si une chaîne est un JSON valide en Python?

En Python, existe-t-il un moyen de vérifier si une chaîne est un JSON valide avant d'essayer de l'analyser?

Par exemple, avec l'API Graph de Facebook, elle renvoie parfois du JSON, parfois un fichier image.

152
Joey Blake

Vous pouvez essayer de faire json.loads(), ce qui jettera un ValueError si la chaîne que vous passez ne peut pas être décodée au format JSON.

En général, la philosophie " Pythonic " pour ce genre de situation s'appelle EAFP , car est plus facile à demander que le pardon que la permission .

196
John Flatness

Exemple Python le script renvoie un booléen si une chaîne est valide. Json:

import json

def is_json(myjson):
  try:
    json_object = json.loads(myjson)
  except ValueError as e:
    return False
  return True

Quelles impressions:

print is_json("{}")                          #prints True
print is_json("{asdf}")                      #prints False
print is_json('{ "age":100}')                #prints True
print is_json("{'age':100 }")                #prints False
print is_json("{\"age\":100 }")              #prints True
print is_json('{"age":100 }')                #prints True
print is_json('{"foo":[5,6.8],"foo":"bar"}') #prints True

Convertit une chaîne JSON en un dictionnaire Python:

import json
mydict = json.loads('{"foo":"bar"}')
print(mydict['foo'])    #prints bar

mylist = json.loads("[5,6,7]")
print(mylist)
[5, 6, 7]

Convertit un objet python en chaîne JSON:

foo = {}
foo['gummy'] = 'bear'
print(json.dumps(foo))           #prints {"gummy": "bear"}

Si vous souhaitez accéder à l'analyse syntaxique de bas niveau, n'utilisez pas la vôtre, utilisez une bibliothèque existante: http://www.json.org/

Grand tutoriel sur python module JSON: https://pymotw.com/2/json/

Est-ce que String est JSON et affiche les erreurs de syntaxe et les messages d'erreur:

Sudo cpan JSON::XS
echo '{"foo":[5,6.8],"foo":"bar" bar}' > myjson.json
json_xs -t none < myjson.json

Impressions:

, or } expected while parsing object/hash, at character offset 28 (before "bar}
at /usr/local/bin/json_xs line 183, <STDIN> line 1.

json_xs est capable de vérifier, d’analyser, de prittifier, de coder, de décoder et plus encore la syntaxe:

https://metacpan.org/pod/json_xs

120
Eric Leschinski

Je dirais que l’analyse est la seule façon de vraiment dire. Les exceptions seront déclenchées par la fonction json.loads() de python (presque certainement) si ce n'est pas le bon format. Cependant, aux fins de votre exemple, vous pouvez probablement simplement vérifier les deux premiers caractères non blancs.

Je ne connais pas bien le JSON que facebook renvoie, mais la plupart des chaînes JSON des applications Web commencent par un crochet vide [ ou bouclé {. Je ne connais aucun format d'image qui commence par ces caractères.

Inversement, si vous connaissez les formats d'image susceptibles d'être affichés, vous pouvez vérifier le début de la chaîne pour en savoir plus sur les signatures permettant d'identifier les images et présumer que vous disposez du format JSON s'il ne s'agit pas d'une image.

Un autre moyen simple d'identifier un graphique, plutôt qu'une chaîne de texte, dans le cas où vous cherchez un graphique, consiste simplement à tester les caractères non-ASCII dans la première vingtaine de caractères de la chaîne (en supposant que le JSON est ASCII ).

2
Tim

J'ai proposé une solution générique et intéressante à ce problème:

class SafeInvocator(object):
    def __init__(self, module):
        self._module = module

    def _safe(self, func):
        def inner(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except:
                return None

        return inner

    def __getattr__(self, item):
        obj = getattr(self.module, item)
        return self._safe(obj) if hasattr(obj, '__call__') else obj

et vous pouvez l'utiliser comme ceci:

safe_json = SafeInvocator(json)
text = "{'foo':'bar'}"
item = safe_json.loads(text)
if item:
    # do something
0
odedlaz