Python urllib2: recevoir une réponse JSON de l'url


88

J'essaye d'obtenir une URL en utilisant Python et la réponse est JSON. Cependant, quand je cours

import urllib2
response = urllib2.urlopen('https://api.instagram.com/v1/tags/pizza/media/XXXXXX')
html=response.read()
print html

Le html est de type str et j'attends un JSON. Existe-t-il un moyen de capturer la réponse sous forme de JSON ou d'un dictionnaire python au lieu d'un str.


1
Renvoie-t-il response.read()une chaîne JSON valide?
Martijn Pieters

Oui, c'est une chaîne JSON valide, c'est juste ou tapez str et non dict
Deepak B

S'il s'agit d'une représentation JSON d'une chaîne, plutôt que d'une représentation JSON d'un objet (dict), vous ne pouvez pas forcer le serveur à vous renvoyer des données différentes; vous devez probablement faire une demande différente. Si c'est juste que vous ne savez pas comment analyser une représentation JSON dans l'objet Python équivalent, la réponse de Martjin Pieters est correcte.
abarnert

Réponses:


182

Si l'URL renvoie des données codées JSON valides, utilisez la jsonbibliothèque pour décoder cela:

import urllib2
import json

response = urllib2.urlopen('https://api.instagram.com/v1/tags/pizza/media/XXXXXX')
data = json.load(response)   
print data

1
@ ManuelSchneid3r: La réponse ici est pour Python 2, où la lecture de responsevous donne des chaînes d'octets et json.load()s'attend à lire une chaîne d'octets. JSON doit être encodé à l'aide d'un codec UTF, et ce qui précède fonctionne pour UTF-8, UTF-16 et UTF-32, à condition qu'un point de code BOM soit inclus pour les deux derniers codecs. La réponse à laquelle vous liez suppose que l'UTF-8 a été utilisé, ce qui est généralement correct car c'est la valeur par défaut. Depuis Python 3.6, la jsonbibliothèque décode automatiquement les bytecodes avec des données JSON à condition qu'un encodage UTF soit utilisé.
Martijn Pieters

@ ManuelSchneid3r: Sinon, je vous recommande d'utiliser la requestsbibliothèque, qui détecte également automatiquement le codec UTF correct à utiliser dans les cas où la nomenclature est manquante et aucun jeu de caractères n'a été spécifié dans l'en-tête de la réponse. Utilisez simplement la response.json()méthode.
Martijn Pieters

35
import json
import urllib

url = 'http://example.com/file.json'
r = urllib.request.urlopen(url)
data = json.loads(r.read().decode(r.info().get_param('charset') or 'utf-8'))
print(data)

urllib , pour Python 3.4
HTTPMessage , renvoyé par r.info ()


1
Code solide autre que print dataincorrect pour Python 3. Devrait l'être print(data).
David Metcalfe

1
Oui et la ligne 2 devrait l'être import urllib.request. De plus, ce fichier .json dans l'URL n'existe plus.
hack-tramp

5
"""
Return JSON to webpage
Adding to wonderful answer by @Sanal
For Django 3.4
Adding a working url that returns a json (Source: http://www.jsontest.com/#echo)
"""

import json
import urllib

url = 'http://echo.jsontest.com/insert-key-here/insert-value-here/key/value'
respons = urllib.request.urlopen(url)
data = json.loads(respons.read().decode(respons.info().get_param('charset') or 'utf-8'))
return HttpResponse(json.dumps(data), content_type="application/json")

1
ouf, ce json.dumps () a sauvé ma journée.
Lloyd

Dans le cas de Django 1.7 +, vous pouvez utiliser JsonResponse directement comme suit from django.http import JsonResponse return JsonResponse({'key':'value'})
raton laveur

1
Je faisais json.dump () au lieu de json.dumps (), je me sentais stupide, merci pour la sauvegarde!
Hashir Baig

4

Faites attention à la validation, etc., mais la solution directe est la suivante:

import json
the_dict = json.load(response)

2
resource_url = 'http://localhost:8080/service/'
response = json.loads(urllib2.urlopen(resource_url).read())

1

Bibliothèque standard Python 3 one-liner:

load(urlopen(url))

# imports (place these above the code before running it)
from json import load
from urllib.request import urlopen
url = 'https://jsonplaceholder.typicode.com/todos/1'

0

Bien que je suppose que cela a déjà répondu, je voudrais ajouter mon petit peu à ceci

import json
import urllib2
class Website(object):
    def __init__(self,name):
        self.name = name 
    def dump(self):
     self.data= urllib2.urlopen(self.name)
     return self.data

    def convJSON(self):
         data=  json.load(self.dump())
     print data

domain = Website("https://example.com")
domain.convJSON()

Remarque: l'objet passé à json.load () doit prendre en charge .read () , donc urllib2.urlopen (self.name) .read () ne fonctionnerait pas. Doamin passé doit être fourni avec le protocole dans ce cas http


0

vous pouvez également obtenir json en utilisant requestscomme ci-dessous:

import requests

r = requests.get('http://yoursite.com/your-json-pfile.json')
json_response = r.json()

0

Ceci est une autre solution plus simple à votre question

pd.read_json(data)

où data est la sortie str du code suivant

response = urlopen("https://data.nasa.gov/resource/y77d-th95.json")
json_data = response.read().decode('utf-8', 'replace')

-1

Aucun des exemples fournis ici n'a fonctionné pour moi. Ils étaient soit pour Python 2 (uurllib2), soit ceux pour Python 3 retournent l'erreur "ImportError: No module named request". Je recherche le message d'erreur sur Google et il m'oblige apparemment à installer un module - ce qui est évidemment inacceptable pour une tâche aussi simple.

Ce code a fonctionné pour moi:

import json,urllib
data = urllib.urlopen("https://api.github.com/users?since=0").read()
d = json.loads(data)
print (d)

2
Vous utilisez évidemment Python 2. En Python 3, il n'y en a pas urllib.urlopen; urlopenest dans le urllib.requestmodule.
Nick Matteo
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.