Python urllib2: JSON-Antwort von der URL erhalten

87

Ich versuche, eine URL mit Python abzurufen, und die Antwort lautet JSON. Wenn ich jedoch renne

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

Das HTML ist vom Typ str und ich erwarte einen JSON. Gibt es eine Möglichkeit, die Antwort als JSON oder Python-Wörterbuch anstelle einer str zu erfassen?

Deepak B.
quelle
1
Gibt response.read()eine gültige JSON-Zeichenfolge zurück?
Martijn Pieters
Ja, es ist eine gültige JSON-Zeichenfolge. Sie ist gerecht oder gibt str ein und
Deepak B
Wenn es sich um eine JSON-Darstellung einer Zeichenfolge handelt und nicht um eine JSON-Darstellung eines Objekts (dikt), können Sie den Server nicht zwingen, Ihnen andere Daten zurückzugeben. Sie müssen wahrscheinlich eine andere Anfrage stellen. Wenn Sie nur nicht wissen, wie Sie eine JSON-Darstellung in das entsprechende Python-Objekt analysieren können, ist die Antwort von Martjin Pieters richtig.
Abarnert

Antworten:

182

Wenn die URL gültige JSON-codierte Daten zurückgibt, verwenden Sie die jsonBibliothek, um Folgendes zu dekodieren:

import urllib2
import json

response = urllib2.urlopen('https://api.instagram.com/v1/tags/pizza/media/XXXXXX')
data = json.load(response)   
print data
Martijn Pieters
quelle
1
@ ManuelSchneid3r: Die Antwort hier ist für Python 2, wo das Lesen von responseIhnen Bytestrings liefert und json.load()erwartet, einen Bytestring zu lesen. JSON muss mit einem UTF-Codec codiert werden. Dies funktioniert für UTF-8, UTF-16 und UTF-32, sofern für die beiden letztgenannten Codecs ein Stücklistencodepunkt enthalten ist. Die Antwort, auf die Sie verlinken, setzt voraus, dass UTF-8 verwendet wurde. Dies ist normalerweise richtig, da dies die Standardeinstellung ist. Ab Python 3.6 jsondecodiert die Bibliothek Bytecodes automatisch mit JSON-Daten, sofern eine UTF-Codierung verwendet wird.
Martijn Pieters
@ ManuelSchneid3r: Ansonsten würde ich empfehlen, dass Sie die requestsBibliothek verwenden, die auch automatisch den richtigen UTF-Codec erkennt, der verwendet werden soll, wenn die Stückliste fehlt und im Antwortheader kein Zeichensatz angegeben wurde. Verwenden Sie einfach die response.json()Methode.
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 für Python 3.4
HTTPMessage , zurückgegeben von r.info ()

SanalBathery
quelle
1
Solider Code print data, der für Python 3 nicht falsch ist. Sollte sein print(data).
David Metcalfe
1
Ja und Zeile 2 sollte sein import urllib.request. Außerdem ist diese .json-Datei in der URL nicht mehr vorhanden.
Hack-Tramp
4

Seien Sie vorsichtig bei der Validierung und so weiter, aber die richtige Lösung lautet:

import json
the_dict = json.load(response)
MostafaR
quelle
4
"""
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")
Waschbär
quelle
1
Puh, das json.dumps () hat mir den Tag gerettet.
Lloyd
Im Fall von Django 1.7 + können Sie JsonResponse wie folgt direkt verwenden from django.http import JsonResponse return JsonResponse({'key':'value'})
Waschbär
1
Ich habe json.dump () anstelle von json.dumps () gemacht und mich dumm gefühlt. Danke für das Speichern!
Hashir Baig
2
resource_url = 'http://localhost:8080/service/'
response = json.loads(urllib2.urlopen(resource_url).read())
Jossef Harush
quelle
1

Einzeiler der Python 3-Standardbibliothek:

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'
Adam
quelle
0

Obwohl ich denke, dass es bereits geantwortet hat, möchte ich mein kleines bisschen dazu hinzufügen

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

Hinweis: Objekt an json.load () übergeben sollte .read () unterstützen , daher würde urllib2.urlopen (self.name) .read () nicht funktionieren. Doamin bestanden sollte in diesem Fall mit Protokoll versehen werden http

Nitigya Sharma
quelle
0

Sie können json auch requestswie folgt erhalten:

import requests

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

Dies ist eine weitere einfachere Lösung für Ihre Frage

pd.read_json(data)

Dabei ist data die str-Ausgabe des folgenden Codes

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

Keines der hier angegebenen Beispiele hat für mich funktioniert. Sie waren entweder für Python 2 (uurllib2) oder für Python 3 und geben den Fehler "ImportError: Kein Modul mit dem Namen request" zurück. Ich google die Fehlermeldung und es erfordert anscheinend, dass ich ein Modul installiere - was für eine so einfache Aufgabe offensichtlich nicht akzeptabel ist.

Dieser Code hat bei mir funktioniert:

import json,urllib
data = urllib.urlopen("https://api.github.com/users?since=0").read()
d = json.loads(data)
print (d)
Uxbridge
quelle
2
Sie verwenden offensichtlich Python 2. In Python 3 gibt es keine urllib.urlopen; urlopenist im urllib.requestModul.
Nick Matteo