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.

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


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.


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


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
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, 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))

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 )

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.