HTTP-запросы и разбор JSON в Python

202

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

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? Я хочу отправить такой запрос, получить результат и разобрать его.

Arun
источник

Ответы:

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

zeekay
источник
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.

linkyndy
источник
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'?
3lok
1
В r.json()(из моего ответа) у вас есть фактический ответ, JSON-декодированный. Вы можете получить к нему доступ как обычный list/ dict; print r.json()чтобы увидеть, как это выглядит. Или обратитесь к документации API службы, для которой вы сделали запрос.
linkyndy
37

requestsимеет встроенный .json()метод

import requests
requests.get(url).json()
maow
источник
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
источник
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

Используйте библиотеку запросов, довольно распечатайте результаты, чтобы вы могли лучше найти ключи / значения, которые вы хотите извлечь, а затем используйте вложенные циклы for для анализа данных. В примере я извлекаю пошаговые указания по вождению.

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 (например, в браузере)? Вот что я получаю в своем терминале: [link] 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
0

Также для симпатичной Json на консоли:

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

можно использовать дампы с отступом. (Пожалуйста, импортируйте JSON )

user5510975
источник