Python urllib2:从url接收JSON响应


88

我正在尝试使用Python获取URL,响应为JSON。但是,当我跑步时

import urllib2
response = urllib2.urlopen('https://api.instagram.com/v1/tags/pizza/media/XXXXXX')
html=response.read()
print html

html的类型为str,我期望使用JSON。有什么办法可以将响应捕获为JSON或python字典而不是str。


1
response.read()返回一个有效的JSON字符串?
马丁·皮特斯

是的,它是一个有效的JSON字符串,其正义或键入str而不是dict
Deepak B

如果它是字符串的JSON表示形式,而不是对象(dict)的JSON表示形式,则不能强制服务器返回不同的数据。您可能需要提出其他要求。如果只是您不知道如何将JSON表示形式解析为等效的Python对象,那么Martjin Pieters的答案是正确的。
abarnert

Answers:


182

如果URL返回有效的JSON编码数据,请使用该json库对其进行解码:

import urllib2
import json

response = urllib2.urlopen('https://api.instagram.com/v1/tags/pizza/media/XXXXXX')
data = json.load(response)   
print data

1
@ ManuelSchneid3r:这里的答案是针对Python 2的,从中读取将response提供字节串,并json.load()期望读取字节串。JSON 必须使用UTF编解码器进行编码,并且上面的代码适用于UTF-8,UTF-16和UTF-32,前提是后两个编解码器包含BOM表编码。您链接到的答案假定使用的是UTF-8,这通常是正确的,因为这是默认设置。从Python 3.6开始,json如果使用UTF编码,该库将使用JSON数据自动解码字节码。
马丁·彼得斯

@ ManuelSchneid3r:否则,我建议您使用该requests库,该库还会自动检测出正确的UTF编解码器,以在缺少BOM且在响应标头中未指定任何字符集的情况下使用。只需使用该response.json()方法即可。
马丁·彼得斯

35
import json
import urllib

url = 'http://example.com/file.json'
r = urllib.request.urlopen(url)
data = json.loads(r.read().decode(r.info().get_param('charset') or 'utf-8'))
print(data)

urllib,对于Python 3.4
HTTPMessage,由r.info()返回


1
可靠的代码,而不是print data对Python 3不正确的代码print(data)
David Metcalfe '18

1
是的,第2行应该是import urllib.request。而且,URL中的.json文件不再存在。
hack-tramp

5
"""
Return JSON to webpage
Adding to wonderful answer by @Sanal
For Django 3.4
Adding a working url that returns a json (Source: http://www.jsontest.com/#echo)
"""

import json
import urllib

url = 'http://echo.jsontest.com/insert-key-here/insert-value-here/key/value'
respons = urllib.request.urlopen(url)
data = json.loads(respons.read().decode(respons.info().get_param('charset') or 'utf-8'))
return HttpResponse(json.dumps(data), content_type="application/json")

1
哇,那个json.dumps()挽救了我的一天。
劳埃德

如果是Django 1.7 +,则可以按以下方式直接使用JsonResponse from django.http import JsonResponse return JsonResponse({'key':'value'})
浣熊

1
我在做json.dump()而不是json.dumps(),感觉很蠢,谢谢您的保存!
哈希尔·拜格

4

注意验证等问题,但是直接的解决方案是:

import json
the_dict = json.load(response)

2
resource_url = 'http://localhost:8080/service/'
response = json.loads(urllib2.urlopen(resource_url).read())

1

Python 3标准库一线版:

load(urlopen(url))

# imports (place these above the code before running it)
from json import load
from urllib.request import urlopen
url = 'https://jsonplaceholder.typicode.com/todos/1'

0

虽然我想它已经回答了,但我想在此补充一点

import json
import urllib2
class Website(object):
    def __init__(self,name):
        self.name = name 
    def dump(self):
     self.data= urllib2.urlopen(self.name)
     return self.data

    def convJSON(self):
         data=  json.load(self.dump())
     print data

domain = Website("https://example.com")
domain.convJSON()

注意:传递给json.load()的对象应支持.read(),因此urllib2.urlopen(self.name).read()无效。在这种情况下,应为通过的Doamin提供协议http


0

您还可以通过requests以下方式获取json :

import requests

r = requests.get('http://yoursite.com/your-json-pfile.json')
json_response = r.json()

0

这是您问题的另一个更简单的解决方案

pd.read_json(data)

其中data是以下代码的str输出

response = urlopen("https://data.nasa.gov/resource/y77d-th95.json")
json_data = response.read().decode('utf-8', 'replace')

-1

这里提供的所有示例都不适合我。它们要么用于Python 2(uurllib2),要么用于Python 3,返回错误“ ImportError:没有名为request的模块”。我用谷歌搜索错误消息,它显然需要我安装一个模块-对于这样一个简单的任务显然是不可接受的。

这段代码对我有用:

import json,urllib
data = urllib.urlopen("https://api.github.com/users?since=0").read()
d = json.loads(data)
print (d)

2
您显然正在使用Python2。在Python 3中,没有urllib.urlopen; urlopenurllib.request模块中。
尼克·马特奥
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.