Python中的HTTP请求和JSON解析


202

我想通过Google Directions API动态查询Google Maps。例如,此请求计算通过伊利诺伊州芝加哥市到密苏里州乔普林市和俄克拉荷马州俄克拉荷马市的两个航路点的路线:

http://maps.googleapis.com/maps/api/directions/json?origin = Chicago,IL&destination = Los + Angeles,CA&waypoints = Joplin,MO |俄克拉荷马州+市,OK&sensor = false

以JSON格式返回结果。

如何在Python中执行此操作?我想发送这样的请求,接收结果并解析它。

Answers:


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错误。
demongolem

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 2013年

2
@nyuszika如果您使用的是debian,请尽可能使用pip获取较新的python库。您不想使用旧的python库进行编码,除非有重要的原因要使用apt仓库中的debian。
SHernandez 2014年

@SHernandez这是一个正确的观点,但是某些软件包可能取决于python-requests(或python3-requests)软件包,因此您需要在其他地方安装而不是/usr/local避免破坏那些软件包。另一方面,当可移植性/兼容性微不足道时,我认为这是值得的。
nyuszika7h

3
如何仅从json响应'r'中提取特定的名称/值对?
3lokh 2015年

1
r.json()(根据我的回答)中,您具有JSON解码的实际响应。您可以像普通的list/ 一样访问它dictprint r.json()看看它的样子。或参考您提出要求的服务的API文档。
linkyndy 2015年

37

requests具有内置.json()方法

import requests
requests.get(url).json()

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
感谢您的帮助,但是需要注意以下几点:python.3.0中已删除urllib.urlopen()函数,而使用urllib2.urlopen()。
阿伦(Arun)

2
阿伦,是的,但它不再命名为urllib2
Corey Goldberg

3
这是urllib.request在Python 3
nyuszika7h

这是行不通的。json.loads给出“ TypeError:JSON对象必须为str,而不是“ HTTPResponse””,而json.loads给出“ TypeError:JSON对象必须为str,而不是“ bytes”
M Hornbacher 2015年

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'])
迈克尔(Michael)

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:

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

可以使用带有缩进的转储。(请导入json

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.