Permitir que el objeto JSON acepte bytes o permitir que urlopen las cadenas de salida
Con Python3 estoy solicitando un documento json desde una URL.
response = urllib.request.urlopen(request)
El objeto response
es un objeto similar a un archivo con los métodos read
y readline
.
Normalmente se puede crear un objeto JSON con un archivo abierto en modo texto.
obj = json.load(fp)
Lo que me gustaría hacer es:
obj = json.load(response)
Sin embargo, esto no funciona ya que urlopen devuelve un objeto file en modo binario.
Un trabajo alrededor es, por supuesto:
str_response = response.readall().decode('utf-8')
obj = json.loads(str_response)
Pero esto se siente mal...
¿Hay una mejor manera ¿que puedo transformar un objeto de archivo de bytes en un objeto de archivo de cadena? ¿O me falta algún parámetro para urlopen
o json.load
para dar una codificación?
11 answers
HTTP envía bytes. Si el recurso en cuestión es texto, la codificación de caracteres se especifica normalmente, ya sea por el encabezado HTTP Content-Type o por otro mecanismo (un RFC, HTML meta http-equiv
,...).
urllib
debería saber cómo codificar los bytes en una cadena, pero es demasiado ingenuo-es una horrible falta de potencia y de la onu-de la biblioteca de Python.
Bucear en Python 3 proporciona una visión general sobre la situación.
Su "solución alternativa" está bien, aunque se siente mal, es la forma correcta de hacerlo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-03 18:50:50
La maravillosa biblioteca estándar de Python al rescate {
import codecs
reader = codecs.getreader("utf-8")
obj = json.load(reader(response))
Funciona con py2 y py3.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-23 10:29:57
He llegado a la opinión de que la pregunta es la mejor respuesta:)
import json
from urllib.request import urlopen
response = urlopen("site.com/api/foo/bar").read().decode('utf8')
obj = json.loads(response)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-27 12:55:57
Para cualquier otra persona que intente resolver esto usando la biblioteca requests
:
import json
import requests
r = requests.get('http://localhost/index.json')
r.raise_for_status()
# works for Python2 and Python3
json.loads(r.content.decode('utf-8'))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-13 18:06:42
Este funciona para mí, usé la biblioteca 'request' con json()
echa un vistazo al documento en requests for humans
import requests
url = 'here goes your url'
obj = requests.get(url).json()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-20 03:47:00
Me encontré con problemas similares usando Python 3.4.3 & 3.5.2 y Django 1.11.3. Sin embargo, cuando actualicé a Python 3.6.1 los problemas desaparecieron.
Puedes leer más sobre esto aquí: https://docs.python.org/3/whatsnew/3.6.html#json
Si no está vinculado a una versión específica de Python, solo considere actualizar a 3.6 o posterior.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-12 01:19:14
Si está experimentando este problema mientras usa el microframe del frasco, entonces puede hacer:
data = json.loads(response.get_data(as_text=True))
Desde los documentos:"Si as_text se establece en True, el valor devuelto será una cadena unicode decodificada"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-27 11:17:13
Acabo de encontrar este sencillo método para hacer que el contenido HttpResponse sea un json
import json
request = RequestFactory() # ignore this, this just like your request object
response = MyView.as_view()(request) # got response as HttpResponse object
response.render() # call this so we could call response.content after
json_response = json.loads(response.content.decode('utf-8'))
print(json_response) # {"your_json_key": "your json value"}
Espero que te ayude
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-27 17:26:09
Su solución en realidad me acaba de salvar. Estaba teniendo muchos problemas procesando la solicitud usando el framework Falcon. Esto funcionó para mí. req siendo el formulario de solicitud curl pr httpie
json.loads(req.stream.read().decode('utf-8'))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-09 17:21:37
Esto transmitirá los datos de bytes a json.
import io
obj = json.load(io.TextIOWrapper(response))
Io.TextIOWrapper es preferible al lector de módulos del códec. https://www.python.org/dev/peps/pep-0400 /
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-28 20:30:36
Utilicé el siguiente programa para usar json.loads()
import urllib.request
import json
endpoint = 'https://maps.googleapis.com/maps/api/directions/json?'
api_key = 'AIzaSyABbKiwfzv9vLBR_kCuhO7w13Kseu68lr0'
origin = input('where are you ?').replace(' ','+')
destination = input('where do u want to go').replace(' ','+')
nav_request = 'origin={}&destination={}&key={}'.format(origin,destination,api_key)
request = endpoint + nav_request
**response = urllib.request.urlopen(request).read().decode('utf-8')
directions = json.loads(response)**
print(directions)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-15 01:27:00