Requêtes HTTP et analyse JSON en Python

202

Je souhaite interroger dynamiquement Google Maps via l'API Google Directions. Par exemple, cette demande calcule l'itinéraire de Chicago, IL à Los Angeles, CA via deux waypoints à Joplin, MO et 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

Il renvoie un résultat au format JSON .

Comment puis-je faire cela en Python? Je souhaite envoyer une telle demande, recevoir le résultat et l'analyser.

Arun
la source

Réponses:

348

Je recommande d'utiliser la bibliothèque de requêtes impressionnante :

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

Contenu de la réponse JSON: https://requests.readthedocs.io/en/master/user/quickstart/#json-response-content

Zeekay
la source
2
Pour moi, je devais faire json=paramsau lieu de params=paramsou j'obtiens une erreur 500.
demongolem
140

Le requestsmodule Python s'occupe à la fois de récupérer les données JSON et de les décoder, grâce à son décodeur JSON intégré. Voici un exemple tiré de la documentation du module :

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

Il n'est donc pas nécessaire d'avoir à utiliser un module distinct pour le décodage JSON.

linkyndy
la source
4
Si vous avez besoin d'être compatible avec les demandes 0.x (Debian Wheezy), vous devez utiliser json.load()ou json.loads()plutôt, comme dans 0.x, jsonest une propriété plutôt qu'une fonction.
nyuszika7h
2
@nyuszika Si vous utilisez debian, si possible, utilisez pip pour obtenir des bibliothèques python plus récentes. Vous ne voulez pas coder avec d'anciennes bibliothèques python, à moins qu'il n'y ait une raison importante d'utiliser ce que Debian a dans les référentiels apt.
SHernandez
@SHernandez C'est un point valide, mais certains packages peuvent dépendre du package python-requests(ou python3-requests), vous devrez donc installer ailleurs que /usr/localpour éviter de casser ces packages. En revanche, lorsque la portabilité / compatibilité est triviale, à mon avis, cela en vaut la peine.
nyuszika7h
3
Comment extraire uniquement une paire nom-valeur particulière de la réponse json 'r'?
3lokh
1
Dans r.json()(à partir de ma réponse) vous avez la réponse réelle, décodée JSON. Vous pouvez y accéder comme un normal list/ dict; print r.json()pour voir à quoi ça ressemble. Ou reportez-vous aux documents API du service pour lequel vous avez fait la demande.
linkyndy
37

requestsa une .json()méthode intégrée

import requests
requests.get(url).json()
maow
la source
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))
clyfish
la source
3
Merci pour votre aide, cependant, il convient de noter ce qui suit: La fonction urllib.urlopen () a été supprimée dans Python 3.0 au profit de urllib2.urlopen ().
Arun
2
Arun, oui mais il ne s'appelle plus urllib2
Corey Goldberg
3
C'est urllib.requesten Python 3.
nyuszika7h
Ça ne marche pas. json.loads donne 'TypeError: l'objet JSON doit être str, pas' HTTPResponse '' et json.load donne 'TypeError: l'objet JSON doit être str, pas' bytes ''
M Hornbacher
16

Utilisez la bibliothèque de requêtes, imprimez les résultats de manière à pouvoir localiser mieux les clés / valeurs que vous souhaitez extraire, puis utilisez les boucles imbriquées pour analyser les données. Dans l'exemple, j'extrait des instructions de conduite étape par étape.

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
la source
Michael, comment puis-je comprendre cela une fois que j'ai obtenu les données? Comment l'afficher au format visuel json "classique" (comme celui que vous obtenez dans votre navigateur)? Voici ce que j'obtiens dans mon terminal: [lien] s13.postimg.org/3r55jajk7/terminal.png
Alexander Starbuck
3
@AlexStarbuck import pprintthen ->pprint.pprint(step['html_instructions'])
Michael
7

Essaye ça:

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))
Raghav Gupta
la source
1
demandes a sa propre fonction json
LilaQ
0

Aussi pour la jolie Json sur console:

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

possible d'utiliser des vidages avec retrait. (Veuillez importer json )

user5510975
la source