Python urllib2: Recebe resposta JSON do url

88

Estou tentando OBTER um URL usando Python e a resposta é JSON. No entanto, quando eu corro

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

O html é do tipo str e estou esperando um JSON. Existe alguma maneira de capturar a resposta como JSON ou um dicionário Python em vez de um str.

Deepak B
fonte
1
Está response.read()retornando uma string JSON válida?
Martijn Pieters
Sim, é uma string JSON válida, é apenas ou digite str e não dict
Deepak B
Se for uma representação JSON de uma string, em vez de uma representação JSON de um objeto (dict), você não pode forçar o servidor a retornar dados diferentes; você provavelmente precisará fazer uma solicitação diferente. Se você simplesmente não sabe como analisar uma representação JSON no objeto Python equivalente, a resposta de Martjin Pieters está correta.
abarnert em

Respostas:

182

Se o URL estiver retornando dados codificados em JSON válidos, use a jsonbiblioteca para decodificar:

import urllib2
import json

response = urllib2.urlopen('https://api.instagram.com/v1/tags/pizza/media/XXXXXX')
data = json.load(response)   
print data
Martijn Pieters
fonte
1
@ ManuelSchneid3r: A resposta aqui é para Python 2, em que ler de responsefornece bytestrings e json.load()espera ler uma bytestring. JSON deve ser codificado usando um codec UTF, e o acima funciona para UTF-8, UTF-16 e UTF-32, desde que um codepoint BOM seja incluído para os dois últimos codecs. A resposta que você vincular presume que foi usado UTF-8, o que geralmente está correto porque é o padrão. A partir do Python 3.6, a jsonbiblioteca decodifica automaticamente os bytecodes com dados JSON, desde que uma codificação UTF seja usada.
Martijn Pieters
@ ManuelSchneid3r: Caso contrário, recomendo que você use a requestsbiblioteca, que também detecta automaticamente o codec UTF correto para usar nos casos em que o BOM está ausente e nenhum conjunto de caracteres foi especificado no cabeçalho da resposta. Basta usar o response.json()método.
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 , para Python 3.4
HTTPMessage , retornado por r.info ()

SanalBathery
fonte
1
Código sólido diferente de print dataser incorreto para Python 3. Deveria ser print(data).
David Metcalfe,
1
Sim e a linha 2 deve ser import urllib.request. Além disso, esse arquivo .json no url não existe mais.
hack-tramp de
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")
guaxinim
fonte
1
uau, aquele json.dumps () salvou meu dia.
Lloyd
No caso do Django 1.7 +, você pode usar JsonResponse diretamente da seguinte maneira from django.http import JsonResponse return JsonResponse({'key':'value'})
guaxinim
1
Eu estava fazendo json.dump () em vez de json.dumps (), me sentindo idiota, obrigado por salvar!
Hashir Baig
4

Tenha cuidado com a validação e etc, mas a solução direta é esta:

import json
the_dict = json.load(response)
MostafaR
fonte
2
resource_url = 'http://localhost:8080/service/'
response = json.loads(urllib2.urlopen(resource_url).read())
Jossef Harush
fonte
1

One-liner da biblioteca padrão do 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'
Adão
fonte
0

Embora eu ache que já tenha respondido, eu gostaria de adicionar um pouco mais neste

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: o objeto passado para json.load () deve suportar .read () , portanto urllib2.urlopen (self.name) .read () não funcionaria. Doamin aprovado deve ser fornecido com protocolo neste caso http

Nitigya Sharma
fonte
0

você também pode obter json usando requestso seguinte:

import requests

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

Esta é outra solução mais simples para sua pergunta

pd.read_json(data)

onde data é a saída str do código a seguir

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

Nenhum dos exemplos fornecidos aqui funcionou para mim. Eles eram para Python 2 (uurllib2) ou aqueles para Python 3 retornavam o erro "ImportError: No module named request". Pesquisei no Google a mensagem de erro e aparentemente requer a instalação de um módulo - o que é obviamente inaceitável para uma tarefa tão simples.

Este código funcionou para mim:

import json,urllib
data = urllib.urlopen("https://api.github.com/users?since=0").read()
d = json.loads(data)
print (d)
Uxbridge
fonte
2
Evidentemente, você está usando o Python 2. No Python 3, não há urllib.urlopen; urlopenestá no urllib.requestmódulo.
Nick Matteo