Python urllib2: ricevi la risposta JSON dall'URL


91

Sto cercando di ottenere un URL utilizzando Python e la risposta è JSON. Tuttavia, quando corro

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

L'html è di tipo str e mi aspetto un JSON. C'è un modo per catturare la risposta come JSON o un dizionario Python invece di un str.


1
Sta response.read()restituendo una stringa JSON valida?
Martijn Pieters

Sì, è una stringa JSON valida, è solo o digita str e non dict
Deepak B

Se è una rappresentazione JSON di una stringa, piuttosto che una rappresentazione JSON di un oggetto (dict), non puoi forzare il server a restituirti dati diversi; probabilmente dovrai fare una richiesta diversa. Se è solo che non sai come analizzare una rappresentazione JSON nell'oggetto Python equivalente, la risposta di Martjin Pieters è corretta.
abarnert

Risposte:


184

Se l'URL restituisce dati validi con codifica JSON, utilizza la jsonlibreria per decodificarli:

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 risposta qui è per Python 2, dove leggere da responseti dà bytestring e si json.load()aspetta di leggere bytestring. JSON deve essere codificato utilizzando un codec UTF e quanto sopra funziona per UTF-8, UTF-16 e UTF-32, a condizione che un codepoint BOM sia incluso per gli ultimi due codec. La risposta a cui ti colleghi presume che sia stato utilizzato UTF-8, che di solito è corretto perché è l'impostazione predefinita. A partire da Python 3.6, la jsonlibreria decodifica automaticamente i bytecode con dati JSON a condizione che venga utilizzata una codifica UTF.
Martijn Pieters

@ ManuelSchneid3r: altrimenti consiglierei di utilizzare la requestslibreria, che rileva automaticamente anche il codec UTF corretto da utilizzare nei casi in cui manca il BOM e non è stato specificato alcun set di caratteri nell'intestazione della risposta. Usa il response.json()metodo.
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 , per Python 3.4
HTTPMessage , restituito da r.info ()


1
Codice solido diverso da quello print dataerrato per Python 3. Dovrebbe essere print(data).
David Metcalfe

1
Sì e la riga 2 dovrebbe essere import urllib.request. Inoltre, il file .json nell'URL non esiste più.
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
whew, quel json.dumps () mi ha salvato la giornata.
Lloyd

In caso di Django 1.7 +, puoi usare JsonResponse direttamente come segue from django.http import JsonResponse return JsonResponse({'key':'value'})
procione

1
Stavo facendo json.dump () invece di json.dumps (), sentendomi stupido, grazie per il salvataggio!
Hashir Baig

4

Fai attenzione alla convalida e così via, ma la soluzione diretta è questa:

import json
the_dict = json.load(response)

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

1

Una riga della libreria standard Python 3:

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

Anche se credo che abbia già risposto, vorrei aggiungere la mia parte in questo

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()

Nota: l'oggetto passato a json.load () dovrebbe supportare .read () , quindi urllib2.urlopen (self.name) .read () non funzionerebbe. Doamin passato dovrebbe essere fornito con il protocollo in questo caso http


0

puoi anche ottenere json usando requestscome di seguito:

import requests

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

0

Questa è un'altra soluzione più semplice alla tua domanda

pd.read_json(data)

dove data è l'output di str dal codice seguente

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

-1

Nessuno degli esempi forniti qui ha funzionato per me. Erano per Python 2 (uurllib2) o quelli per Python 3 restituiscono l'errore "ImportError: No module named request". Ho google il messaggio di errore e apparentemente mi richiede di installare un modulo, il che è ovviamente inaccettabile per un'attività così semplice.

Questo codice ha funzionato per me:

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

2
Evidentemente stai usando Python 2. In Python 3, non c'è urllib.urlopen; urlopenè nel urllib.requestmodulo.
Nick Matteo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.