Permintaan HTTP dan JSON parsing dengan Python

202

Saya ingin secara dinamis meminta Google Maps melalui Google Directions API. Sebagai contoh, permintaan ini menghitung rute dari Chicago, IL ke Los Angeles, CA melalui dua titik jalan di Joplin, MO dan Kota Oklahoma, OK:

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

Ini mengembalikan hasil dalam format JSON .

Bagaimana saya bisa melakukan ini dengan Python? Saya ingin mengirim permintaan seperti itu, menerima hasilnya dan menguraikannya.

Arun
sumber

Jawaban:

348

Saya sarankan menggunakan perpustakaan permintaan yang mengagumkan :

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

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

Zeekay
sumber
2
Bagi saya, saya perlu melakukan json=paramsalih - alih params=paramsatau saya mendapatkan kesalahan 500.
demongolem
140

The requestsmodul Python membutuhkan perawatan dari kedua mengambil data JSON dan decoding itu, karena decoder builtin JSON nya. Berikut ini contoh yang diambil dari dokumentasi modul :

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

Jadi tidak ada gunanya harus menggunakan beberapa modul terpisah untuk mendekode JSON.

linkyndy
sumber
4
Jika Anda harus kompatibel dengan permintaan 0.x (Wheezy Debian), Anda harus menggunakan json.load()atau json.loads()sebagai gantinya, seperti dalam 0.x, jsonadalah properti daripada fungsi.
nyuszika7h
2
@nyuszika Jika Anda menggunakan debian, jika mungkin, gunakan pip untuk mendapatkan pustaka python yang lebih baru. Anda tidak ingin kode dengan pustaka python lama, kecuali ada alasan penting untuk menggunakan apa yang dimiliki debian di repositori apt.
SHernandez
@Sernernez Itu adalah poin yang valid, tetapi beberapa paket mungkin bergantung pada python-requests(atau python3-requests) paket, jadi Anda perlu menginstal di tempat lain daripada /usr/localmenghindari melanggar paket-paket itu. Di sisi lain, ketika portabilitas / kompatibilitas sepele, menurut saya itu sepadan.
nyuszika7h
3
Bagaimana cara mengekstrak hanya pasangan nama-nilai tertentu dari json response 'r'?
3lokh
1
Di r.json()(dari jawaban saya) Anda memiliki respons aktual, JSON-decoded. Anda dapat mengaksesnya seperti biasa list/ dict; print r.json()untuk melihat tampilannya. Atau lihat dokumentasi API dari layanan yang Anda minta.
linkyndy
37

requestsmemiliki .json()metode bawaan

import requests
requests.get(url).json()
maow
sumber
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
sumber
3
Terima kasih atas bantuan Anda, namun yang berikut harus diperhatikan: Fungsi urllib.urlopen () telah dihapus dengan Python 3.0 untuk urllib2.urlopen ().
Arun
2
Arun, ya tapi itu tidak lagi bernama urllib2
Corey Goldberg
3
Ada urllib.requestdalam Python 3.
nyuszika7h
Tidak bekerja. json.loads memberikan 'TypeError: objek JSON harus berupa str, bukan' HTTPResponse '' dan json.load memberikan 'TypeError: objek JSON harus str, bukan' byte ''
M Hornbacher
16

Gunakan pustaka permintaan, cukup cetak hasilnya sehingga Anda bisa lebih baik menemukan kunci / nilai yang ingin Anda ekstrak, dan kemudian gunakan nested for loop untuk mem-parsing data. Dalam contoh ini saya mengekstrak petunjuk langkah demi langkah mengemudi.

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
sumber
Michael, bagaimana saya bisa masuk akal dari ini setelah saya mendapatkan data? Bagaimana cara menampilkannya dalam format visual json "klasik" (seperti yang Anda dapatkan di peramban)? Inilah yang saya dapatkan di terminal saya: [tautan] s13.postimg.org/3r55jajk7/terminal.png
Alexander Starbuck
3
@AlexStarbuck import pprintlalu ->pprint.pprint(step['html_instructions'])
Michael
7

Coba ini:

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
sumber
1
permintaan memiliki fungsi json sendiri
LilaQ
0

Juga untuk Json cantik di konsol:

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

mungkin menggunakan dump dengan indent. (Harap impor json )

pengguna5510975
sumber