Python 3获取并解析JSON API

50

我应该如何使用Python解析JSON API响应?我目前有以下代码:

import urllib.request
import json

url = 'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty'

def response(url):
    with urllib.request.urlopen(url) as response:
        return response.read()

res = response(url)
print(json.loads(res))

我遇到了这个错误: TypeError: JSON对象必须是 str 类型,而不是 'bytes'

对于处理json接口,有什么符合python规范的方法吗?

5个回答

63

版本1:(在运行脚本之前执行pip install requests

import requests
r = requests.get(url='https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty')
print(r.json())

版本2:(在运行脚本之前执行pip install wget

import wget

fs = wget.download(url='https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty')
with open(fs, 'r') as f:
    content = f.read()
print(content)

47

您可以使用Python3标准库:

import urllib.request
import json
url = 'http://www.reddit.com/r/all/top/.json'
req = urllib.request.Request(url)

##parsing response
r = urllib.request.urlopen(req).read()
cont = json.loads(r.decode('utf-8'))
counter = 0

##parcing json
for item in cont['data']['children']:
    counter += 1
    print("Title:", item['data']['title'], "\nComments:", item['data']['num_comments'])
    print("----")

##print formated
#print (json.dumps(cont, indent=4, sort_keys=True))
print("Number of titles: ", counter)

输出将会像这样:
...
Title: Maybe we shouldn't let grandma decide things anymore.  
Comments: 2018
---- 
Title: Carrie Fisher and Her Stunt Double Sunbathing on the Set of Return of The Jedi, 1982  
Comments: 880
---- 
Title: fidget spinner  
Comments: 1537
---- 
Number of titles:  25

7

我通常会使用 requests 包和 json 包。以下代码应该符合您的需求:

import requests
import json

url = 'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty'
r = requests.get(url)
print(json.loads(r.content))

输出

[11008076, 
 11006915, 
 11008202,
 ...., 
 10997668,
 10999859,
 11001695]

使用 requests 是解决这个问题最容易使用的方法。 - ferdy
1
我正在使用Python 3.5,但出现了这个错误:AttributeError: module 'requests' has no attribute 'get'。有什么解决方法吗? - ClickThisNick
1
你可能没有安装它 - 尝试从命令行运行 pip install requests - gtlambert
1
我已经尝试过了,但是出现了错误:JSON对象必须是str类型,而不是'bytes'... 你有什么想法吗? - pookie
@pookie 试着使用:print(json.loads(r.text)),你可以检查一下差异,只需使用:type(r.text) type(r.content)。 - Lokendra Singh Rawat

3
原问题中唯一缺失的是在响应对象上调用decode方法(即使对于每个python3版本也不是必须的)。可惜没有人指出这一点,而是都转向了第三方库。
仅使用标准库,针对最简单的用例:
import json
from urllib.request import urlopen


def get(url, object_hook=None):
    with urlopen(url) as resource:  # 'with' is important to close the resource after use
        return json.load(resource, object_hook=object_hook)

简单应用案例:

data = get('http://url') # '{ "id": 1, "$key": 13213654 }'
print(data['id']) # 1
print(data['$key']) # 13213654

或者如果您愿意,但风险更高:
from types import SimpleNamespace

data = get('http://url', lambda o: SimpleNamespace(**o)) # '{ "id": 1, "$key": 13213654 }'
print(data.id) # 1
print(data.$key) # invalid syntax
# though you can still do
print(data.__dict__['$key'])

1

使用Python 3

import requests
import json

url = 'http://IP-Address:8088/ws/v1/cluster/scheduler'
r = requests.get(url)
data = json.loads(r.content.decode())

import requests - Mitchell Currie
并且import json,这段代码片段将可以直接复制粘贴使用。简洁明了的回答,别无他意。 - Mitchell Currie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接