HTTP-запити та JSON-розбір на Python


202

Я хочу динамічно запитувати Карти Google через API Напрямки Google. Як приклад, цей запит розраховує маршрут з Чикаго, штат Ілінойс до Лос-Анджелеса, Каліфорнія через дві маршрутні точки в Джоплін, штат Міссурі та Оклахома-Сіті, ОК:

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

Він повертає результат у форматі JSON .

Як я можу це зробити в Python? Я хочу надіслати такий запит, отримати результат і проаналізувати його.

Відповіді:


348

Рекомендую використовувати бібліотеку дивовижних запитів :

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: https://requests.readthedocs.io/en/master/user/quickstart/#json-response-content


2
Для мене мені потрібно було зробити json=paramsзамість цього params=paramsабо я отримаю помилку 500.
демонголем

140

Модуль requestsPython піклується як про отримання даних JSON, так і про їх розшифровку завдяки вбудованому декодеру JSON. Ось приклад, взятий з документації модуля :

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

Тому немає необхідності використовувати якийсь окремий модуль для декодування JSON.


4
Якщо вам потрібно бути сумісним із запитами 0.x (Debian wheezy), вам слід використовувати json.load()або json.loads()замість цього, як у 0.x, jsonвластивість, а не функцію.
nyuszika7h

2
@nyuszika Якщо ви використовуєте debian, якщо це можливо, використовуйте pip, щоб отримати новіші бібліотеки python. Ви не хочете кодувати зі старими бібліотеками python, якщо немає важливих причин використовувати те, що debian має в сховищах apt.
Шернандес

@SHernandez Це дійсна точка, але деякі пакети можуть залежати від python-requests(або python3-requests) пакету, тому вам потрібно буде встановити десь інше, ніж /usr/localуникнути зламу цих пакетів. З іншого боку, коли портативність / сумісність є тривіальною, на мою думку, вона того варта.
nyuszika7h

3
Як витягти лише конкретну пару імен-значень з відповіді json 'r'?
3лох

1
В r.json()(з моєї відповіді) ви маєте фактичну відповідь, розшифровану JSON. Ви можете отримати доступ до нього як звичайний list/ dict; print r.json()щоб побачити, як це виглядає. Або зверніться до документів API служби, для якої ви зробили запит.
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
Дякуємо за вашу допомогу, проте слід зазначити наступне: Функція urllib.urlopen () була видалена в Python 3.0 на користь urllib2.urlopen ().
Арун

2
Арун, так, але його більше не називають urllib2
Корі Голдберг

3
Це urllib.requestв Python 3.
nyuszika7h

Це не працює. json.loads дає "TypeError: об'єкт JSON повинен бути str, а не HTTPResponse", а json.load дає "TypeError: об'єкт JSON повинен бути str, а не" bytes "
M Hornbacher

16

Використовуйте бібліотеку запитів, досить роздруковуйте результати, щоб ви могли краще знайти ключі / значення, які ви бажаєте витягти, а потім використовувати вкладені для циклів для аналізу даних. У прикладі я дістаю покрокові вказівки руху.

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']

Майкл, як я можу мати певний сенс від цього, як тільки отримаю дані? Як відобразити його у "класичному" візуальному форматі json (на зразок того, який ви отримуєте у своєму браузері)? Ось що я отримую в своєму терміналі: [посилання] s13.postimg.org/3r55jajk7/terminal.png
Олександр Старбак

3
@AlexStarbuck import pprintтоді ->pprint.pprint(step['html_instructions'])
Майкл

7

Спробуйте це:

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
у запитів є своя функція json
LilaQ

0

Також для симпатичного Джсона на консолі:

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

можливо використовувати відвали з відступом. (Будь ласка, імпортуйте json )

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.