web-dev-qa-db-fra.com

Chargement d'un objet JSON en Python à l'aide des modules urllib.request et json

J'ai des problèmes à faire en sorte que les modules "json" et "urllib.request" fonctionnent ensemble dans un simple test de script Python. En utilisant Python 3.5 et voici le code:

import json
import urllib.request

urlData = "http://api.openweathermap.org/data/2.5/weather?q=Boras,SE"
webURL = urllib.request.urlopen(urlData)
print(webURL.read())
JSON_object = json.loads(webURL.read()) #this is the line that doesn't work

Lorsque j'exécute un script en ligne de commande, l'erreur que je reçois est " TypeError: l'objet JSON doit être str, et non pas" octets "". Je suis nouveau sur Python, il existe donc probablement une solution très simple. Appréciez toute aide ici. 

10
David Rådesjö

À part oublier de décoder, vous ne pouvez lire que la réponse une fois. Ayant déjà appelé .read(), le deuxième appel renvoie une chaîne vide.

Appelez .read() juste une fois, et decode les données en chaîne:

data = webURL.read()
print(data)
encoding = webURL.info().get_content_charset('utf-8')
JSON_object = json.loads(data.decode(encoding))

L'appel response.info().get_content_charset() vous indique quel jeu de caractères est utilisé par le serveur.

Démo:

>>> import json
>>> import urllib.request
>>> urlData = "http://api.openweathermap.org/data/2.5/weather?q=Boras,SE"
>>> webURL = urllib.request.urlopen(urlData)
>>> data = webURL.read()
>>> encoding = webURL.info().get_content_charset('utf-8')
>>> json.loads(data.decode(encoding))
{'coord': {'lat': 57.72, 'lon': 12.94}, 'visibility': 10000, 'name': 'Boras', 'main': {'pressure': 1021, 'humidity': 71, 'temp_min': 285.15, 'temp': 286.39, 'temp_max': 288.15}, 'id': 2720501, 'weather': [{'id': 802, 'description': 'scattered clouds', 'icon': '03d', 'main': 'Clouds'}], 'wind': {'speed': 5.1, 'deg': 260}, 'sys': {'type': 1, 'country': 'SE', 'sunrise': 1443243685, 'id': 5384, 'message': 0.0132, 'sunset': 1443286590}, 'dt': 1443257400, 'cod': 200, 'base': 'stations', 'clouds': {'all': 40}}
21
Martijn Pieters

Comme je m'étudie moi-même, il vous suffit d’utiliser la fonction decode('utf-8'), puis d’utiliser la fonction json.load() pour l’extraire au format json.

>>> import json
>>> import urllib.request

>>> urlData = "http://api.openweathermap.org/data/2.5/weather?q=Boras,SE"
>>> webURL = urllib.request.urlopen(urlData)
>>> data = webURL.read()
>>> JSON_object = json.loads(data.decode('utf-8'))
{'coord': {'lat': 57.72, 'lon': 12.94}, 'visibility': 10000, 'name': 'Boras', 'main': {'pressure': 1021, 'humidity': 71, 'temp_min': 285.15, 'temp': 286.39, 'temp_max': 288.15}, 'id': 2720501, 'weather': [{'id': 802, 'description': 'scattered clouds', 'icon': '03d', 'main': 'Clouds'}], 'wind': {'speed': 5.1, 'deg': 260}, 'sys': {'type': 1, 'country': 'SE', 'sunrise': 1443243685, 'id': 5384, 'message': 0.0132, 'sunset': 1443286590}, 'dt': 1443257400, 'cod': 200, 'base': 'stations', 'clouds': {'all': 40}}
0
Jay Patel