Solicitudes HTTP y análisis JSON en Python


202

Quiero consultar dinámicamente Google Maps a través de la API de Google Directions. Como ejemplo, esta solicitud calcula la ruta desde Chicago, IL a Los Ángeles, CA a través de dos puntos de referencia en Joplin, MO y Oklahoma City, OK:

http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|Oklahoma+City,OK&sensor=false

Devuelve un resultado en el formato JSON .

¿Cómo puedo hacer esto en Python? Quiero enviar dicha solicitud, recibir el resultado y analizarlo.

Respuestas:


348

Recomiendo usar la impresionante biblioteca de solicitudes :

import requests

url = 'http://maps.googleapis.com/maps/api/directions/json'

params = dict(
    origin='Chicago,IL',
    destination='Los+Angeles,CA',
    waypoints='Joplin,MO|Oklahoma+City,OK',
    sensor='false'
)

resp = requests.get(url=url, params=params)
data = resp.json() # Check the JSON Response Content documentation below

Contenido de respuesta JSON: https://requests.readthedocs.io/en/master/user/quickstart/#json-response-content


2
Para mí, tenía que hacer en json=paramslugar de params=paramsu obtengo un error 500.
demongolem

140

El requestsmódulo Python se encarga tanto de recuperar datos JSON como de decodificarlos, debido a su decodificador JSON incorporado. Aquí hay un ejemplo tomado de la documentación del módulo :

>>> import requests
>>> r = requests.get('https://github.com/timeline.json')
>>> r.json()
[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

Por lo tanto, no tiene sentido usar un módulo separado para decodificar JSON.


44
Si necesita ser compatible con las solicitudes 0.x (Debian wheezy), debe usar json.load()o json.loads(), como en 0.x, jsones una propiedad en lugar de una función.
nyuszika7h

2
@nyuszika Si está utilizando Debian, si es posible, use pip para obtener nuevas bibliotecas de Python. No desea codificar con bibliotecas antiguas de Python, a menos que haya una razón importante para usar lo que Debian tiene en los repositorios apt.
SHernandez

@SHernandez Ese es un punto válido, pero algunos paquetes pueden depender del python-requests(o python3-requests) paquete, por lo que deberá instalarlo en otro lugar que /usr/localno sea romper esos paquetes. Por otro lado, cuando la portabilidad / compatibilidad es trivial, en mi opinión, vale la pena.
nyuszika7h

3
¿Cómo extraer solo un par nombre-valor particular de la respuesta json 'r'?
3lokh

1
En r.json()(de mi respuesta) tienes la respuesta real, decodificada por JSON. Puedes acceder a él como un normal list/ dict; print r.json()para ver cómo se ve. O consulte los documentos de la API del servicio que solicitó.
linkyndy

37

requeststiene un .json()método incorporado

import requests
requests.get(url).json()

25
import urllib
import json

url = 'http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|Oklahoma+City,OK&sensor=false'
result = json.load(urllib.urlopen(url))

3
Gracias por su ayuda, sin embargo, se debe tener en cuenta lo siguiente: La función urllib.urlopen () se ha eliminado en Python 3.0 a favor de urllib2.urlopen ().
Arun

2
Arun, sí, pero ya no se llama urllib2
Corey Goldberg

3
Está urllib.requesten Python 3.
nyuszika7h

No funciona. json.loads da 'TypeError: el objeto JSON debe ser str, no' HTTPResponse '' y json.load da 'TypeError: el objeto JSON debe ser str, no' bytes '
M Hornbacher

16

Use la biblioteca de solicitudes, imprima los resultados de manera bonita para que pueda localizar mejor las claves / valores que desea extraer, y luego use anidados para bucles para analizar los datos. En el ejemplo extraigo instrucciones de manejo paso a paso.

import json, requests, pprint

url = 'http://maps.googleapis.com/maps/api/directions/json?'

params = dict(
    origin='Chicago,IL',
    destination='Los+Angeles,CA',
    waypoints='Joplin,MO|Oklahoma+City,OK',
    sensor='false'
)


data = requests.get(url=url, params=params)
binary = data.content
output = json.loads(binary)

# test to see if the request was valid
#print output['status']

# output all of the results
#pprint.pprint(output)

# step-by-step directions
for route in output['routes']:
        for leg in route['legs']:
            for step in leg['steps']:
                print step['html_instructions']

Michael, ¿cómo puedo entender esto una vez que obtuve los datos? ¿Cómo lo visualizo en formato visual "clásico" json (como el que obtienes en tu navegador)? Esto es lo que obtengo en mi terminal: [link] s13.postimg.org/3r55jajk7/terminal.png
Alexander Starbuck

3
@AlexStarbuck import pprintentonces ->pprint.pprint(step['html_instructions'])
Michael

7

Prueba esto:

import requests
import json

# Goole Maps API.
link = 'http://maps.googleapis.com/maps/api/directions/json?origin=Chicago,IL&destination=Los+Angeles,CA&waypoints=Joplin,MO|Oklahoma+City,OK&sensor=false'

# Request data from link as 'str'
data = requests.get(link).text

# convert 'str' to Json
data = json.loads(data)

# Now you can access Json 
for i in data['routes'][0]['legs'][0]['steps']:
    lattitude = i['start_location']['lat']
    longitude = i['start_location']['lng']
    print('{}, {}'.format(lattitude, longitude))

1
request tiene su propia función json
LilaQ

0

También para la bonita Json en consola:

 json.dumps(response.json(), indent=2)

posible usar volcados con sangría. ( Importa json )

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.