Python 中的 HTTP 请求和 JSON 解析

Posted

技术标签:

【中文标题】Python 中的 HTTP 请求和 JSON 解析【英文标题】:HTTP requests and JSON parsing in Python 【发布时间】:2011-09-17 04:42:59 【问题描述】:

我想通过 Google Directions 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

它返回一个结果in the JSON format。

如何在 Python 中做到这一点?我想发送这样一个请求,接收结果并解析它。

【问题讨论】:

【参考方案1】:
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))

【讨论】:

感谢您的帮助,但需要注意以下几点: urllib.urlopen() 函数已在 Python 3.0 中被删除,取而代之的是 urllib2.urlopen()。 Arun,是的,但它不再命名为 urllib2 在 Python 3 中是 urllib.request 它不起作用。 json.loads 给出 'TypeError: the JSON object must be str, not 'HTTPResponse'' 而 json.load 给出 'TypeError: the JSON object must be str, not 'bytes'' 又错了@nyuszika7h。它会给你'模块对象不可调用'【参考方案2】:

我建议使用很棒的 requests 库:

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

【讨论】:

对我来说,我需要使用json=params 而不是params=params,否则我会收到 500 错误。【参考方案3】:

使用 requests 库,漂亮地打印结果,以便您可以更好地定位要提取的键/值,然后使用嵌套的 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 @AlexStarbuck import pprint then -> pprint.pprint(step['html_instructions'])【参考方案4】:

由于其内置的 JSON 解码器,requests Python 模块负责检索 JSON 数据并对其进行解码。这是取自the module's documentation的示例:

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

因此,不必使用一些单独的模块来解码 JSON。

【讨论】:

如果你需要兼容 requests 0.x (Debian wheezy),你应该使用 json.load()json.loads() 代替,因为在 0.x 中,json 是一个属性而不是一个函数。 @nyuszika 如果您使用的是 debian,如果可能,请使用 pip 获取更新的 python 库。您不想使用旧的 python 库进行编码,除非有重要的理由使用 apt 存储库中的 debian。 @SHernandez 这是一个正确的观点,但某些软件包可能依赖于 python-requests(或 python3-requests)软件包,因此您需要安装 /usr/local 以外的其他位置以避免破坏这些软件包.另一方面,当可移植性/兼容性微不足道时,我认为这是值得的。 如何从 json 响应 'r' 中仅提取特定的名称-值对? r.json()(来自我的回答)中,您有实际的响应,JSON 解码。您可以像普通的list/dict 一样访问它; print r.json() 看看它的样子。或者参考您提出请求的服务的 API 文档。【参考方案5】:

requests 有内置的.json() 方法

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

【讨论】:

【参考方案6】:

试试这个:

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

【讨论】:

【参考方案7】:

也适用于控制台上的漂亮 Json:

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

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

【讨论】:

【参考方案8】:

只需 import requests 并使用 json() 方法:

source = requests.get("url").json()
print(source)

或者你可以使用这个:

import json,urllib.request
data = urllib.request.urlopen("url").read()
output = json.loads(data)
print (output)

【讨论】:

以上是关于Python 中的 HTTP 请求和 JSON 解析的主要内容,如果未能解决你的问题,请参考以下文章

通过 iis 上的 python 脚本处理带有 json 的 http post 请求

格式化嵌套 json 以用于 Python 请求

python 解析ajax请求带有json参数,请求方式是post的url(注意:参数的json格式的)

使用JSON处理GET和POST请求的简单Python服务器

网络请求框架OkHttp3全解系列:OkHttp的基本使用

如何解压缩数据框列中存在的 json 的键,值将转换为键作为列,而使用 python 将其值转换为列?