HTTP-Anforderungen und JSON-Analyse in Python

202

Ich möchte Google Maps dynamisch über die Google Directions-API abfragen. Diese Anfrage berechnet beispielsweise die Route von Chicago, IL nach Los Angeles, CA über zwei Wegpunkte in Joplin, MO und 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

Es wird ein Ergebnis im JSON-Format zurückgegeben .

Wie kann ich das in Python machen? Ich möchte eine solche Anfrage senden, das Ergebnis erhalten und es analysieren.

Arun
quelle

Antworten:

348

Ich empfehle die Verwendung der fantastischen Anforderungsbibliothek :

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

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

Zeekay
quelle
2
Für mich musste ich json=paramsstattdessen tun params=paramsoder ich bekomme einen 500 Fehler.
Demongolem
140

Das requestsPython-Modul übernimmt aufgrund seines integrierten JSON-Decoders sowohl das Abrufen als auch das Decodieren von JSON-Daten. Hier ist ein Beispiel aus der Dokumentation des Moduls :

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

Es ist also nicht sinnvoll, ein separates Modul zum Decodieren von JSON zu verwenden.

Linkyndy
quelle
4
Wenn Sie mit den Anforderungen 0.x (Debian wheezy) kompatibel sein müssen, sollten Sie verwenden json.load()oder json.loads()stattdessen, wie in 0.x, jsoneher eine Eigenschaft als eine Funktion.
Nyuszika7h
2
@nyuszika Wenn Sie Debian verwenden, verwenden Sie, wenn möglich, pip, um neuere Python-Bibliotheken zu erhalten. Sie möchten nicht mit alten Python-Bibliotheken codieren, es sei denn, es gibt einen wichtigen Grund, das zu verwenden, was Debian in den apt-Repositorys hat.
SHernandez
@SHernandez Das ist ein gültiger Punkt, aber einige Pakete hängen möglicherweise vom python-requests(oder python3-requests) Paket ab. Sie müssen sie also an einem anderen Ort installieren, als um /usr/localzu vermeiden, dass diese Pakete beschädigt werden. Wenn Portabilität / Kompatibilität jedoch trivial ist, lohnt es sich meiner Meinung nach.
Nyuszika7h
3
Wie extrahiere ich nur ein bestimmtes Name-Wert-Paar aus der JSON-Antwort 'r'?
3lokh
1
In r.json()(aus meiner Antwort) haben Sie die tatsächliche Antwort, JSON-decodiert. Sie können wie ein normales list/ darauf zugreifen dict. print r.json()um zu sehen, wie es aussieht. Oder lesen Sie die API-Dokumente des Dienstes, für den Sie die Anforderung gestellt haben.
Linkyndy
37

requestshat eingebaute .json()Methode

import requests
requests.get(url).json()
maow
quelle
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
quelle
3
Vielen Dank für Ihre Hilfe, jedoch ist Folgendes zu beachten: Die Funktion urllib.urlopen () wurde in Python 3.0 zugunsten von urllib2.urlopen () entfernt.
Arun
2
Arun, ja, aber es heißt nicht mehr urllib2
Corey Goldberg
3
Es ist urllib.requestin Python 3.
Nyuszika7h
Es funktioniert nicht. json.loads gibt 'TypeError: Das JSON-Objekt muss str sein, nicht' HTTPResponse '' und json.load gibt 'TypeError: Das JSON-Objekt muss str sein, nicht' bytes ''
M Hornbacher
16

Verwenden Sie die Anforderungsbibliothek, drucken Sie die Ergebnisse hübsch aus, damit Sie die zu extrahierenden Schlüssel / Werte besser finden können, und verwenden Sie dann verschachtelte for-Schleifen, um die Daten zu analysieren. Im Beispiel extrahiere ich Schritt für Schritt Wegbeschreibungen.

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
quelle
Michael, wie kann ich daraus einen Sinn machen, wenn ich die Daten habe? Wie zeige ich es im "klassischen" json-visuellen Format an (wie das, das Sie in Ihrem Browser erhalten)? Folgendes
Alexander Starbuck
3
@ AlexStarbuck import pprintdann ->pprint.pprint(step['html_instructions'])
Michael
7

Versuche dies:

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
quelle
1
Anfragen hat seine eigene
JSON-
0

Auch für hübschen Json auf der Konsole:

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

Dumps mit Einzug können verwendet werden. (Bitte json importieren )

user5510975
quelle