2009-10-28 33 views
38

我想这必须有一个简单的答案,但我挣扎着:我想要一个url(它输出json)并获取python中可用字典中的数据。我被困在最后一步。通过网址获取json数据并在Python中使用(simplejson)

>>> import urllib2 
>>> import simplejson 
>>> req = urllib2.Request("http://vimeo.com/api/v2/video/38356.json", None, {'user-agent':'syncstream/vimeo'}) 
>>> opener = urllib2.build_opener() 
>>> f = opener.open(req) 
>>> f.read()    # this works 
'[{"id":"38356","title":"Forgetfulness - Billy Collins Animated Poetry","description":"US Poet Laureate Billy Collins reads his poem ","url":"http:\\/\\/vimeo.com\\/38356","upload_date":"2006-01-24 15:21:03","thumbnail_small":"http:\\/\\/80.media.vimeo.com\\/d1\\/5\\/47\\/74\\/thumbnail-4774968.jpg","thumbnail_medium":"http:\\/\\/80.media.vimeo.com\\/d1\\/5\\/46\\/85\\/thumbnail-4685118.jpg","thumbnail_large":"http:\\/\\/images.vimeo.com\\/87\\/39\\/873998\\/873998_640x480.jpg","user_name":"smjwt","user_url":"http:\\/\\/vimeo.com\\/smjwt","user_portrait_small":"http:\\/\\/bitcast.vimeo.com\\/vimeo\\/portraits\\/defaults\\/d.30.jpg","user_portrait_medium":"http:\\/\\/bitcast.vimeo.com\\/vimeo\\/portraits\\/defaults\\/d.75.jpg","user_portrait_large":"http:\\/\\/bitcast.vimeo.com\\/vimeo\\/portraits\\/defaults\\/d.100.jpg","user_portrait_huge":"http:\\/\\/bitcast.vimeo.com\\/vimeo\\/portraits\\/defaults\\/d.300.jpg","stats_number_of_likes":"281","stats_number_of_plays":"9173","stats_number_of_comments":23,"duration":"112","width":"320","height":"240","tags":"poetry, poet, online poetry, famous poet, video poetry, modern poetry, famous poem, poetry sites, poetry websites, audio poetry, american poet, animation clips, american poetry, free poetry sites, animation art, free poetry, animated clips, poem, poet laureate"}]' 
>>> simplejson.load(f) 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "/usr/lib/python2.5/site-packages/django/utils/simplejson/__init__.py", line 298, in load 
    parse_constant=parse_constant, **kw) 
    File "/usr/lib/python2.5/site-packages/django/utils/simplejson/__init__.py", line 338, in loads 
    return _default_decoder.decode(s) 
    File "/usr/lib/python2.5/site-packages/django/utils/simplejson/decoder.py", line 326, in decode 
    obj, end = self.raw_decode(s, idx=_w(s, 0).end()) 
    File "/usr/lib/python2.5/site-packages/django/utils/simplejson/decoder.py", line 344, in raw_decode 
    raise ValueError("No JSON object could be decoded") 
ValueError: No JSON object could be decoded 

任何想法,我错了吗?

+3

简单的事情第一:片段中的f.read()仅用于解释的目的,对吗?要问的原因是因为如果它是预期代码的一部分,这就会产生“清空”f的效果,因此ValueError w/simplejason。 – mjv 2009-10-28 23:17:25

+1

django.utils.simplejson已弃用;改用json。 – ifischer 2013-09-24 07:18:39

回答

43

尝试

f = opener.open(req) 
simplejson.load(f) 

没有()首先运行f.read。当你运行f.read()时,文件句柄的内容会变得混乱,所以当你的调用没有任何东西时simplejson.load(f)

+1

谢谢 - 我只是一步一步来确保我可以看到数据...显然,对read()不够了解!谢谢。 – thornomad 2009-10-28 23:19:17

+0

在python 3中,simplejson被替换为json,并且它需要从字节进行转换。 data = json.loads(str(opener.open(req).read(),“utf-8”))将用于UTF-8编码响应。 – Mead 2011-04-28 07:29:00

+2

nit以上 - “utf-8”转换使用'loads',而不是'str'(至少在python 2.7.3中)〜'data = json.loads(str(opener.open(req).read()) ,“utf-8”)' – 2012-05-03 04:24:40

10

第一行读取整个文件。然后,第二行试图从文件中读取更多的,但什么都不剩:

>>> f.read()    # this works 
blah blah blah 
>>> simplejson.load(f) 

要么只是省略f.read()线,或保存从读出的值,并在负荷使用它:

json = f.read() 
simplejson.loads(json) 
-7

有一个更简单的方法 - 你根本不需要simplejson。只要您将true/false/null设置为正确的值,Python就可以使用eval语句将json解析为字典/数组。

# fetch the url 
url = "https://api.twitter.com/1/users/lookup.json?user_id=6253282,18949452" 
json = urllib2.urlopen(url).read() 

# convert to a native python object 
(true,false,null) = (True,False,None) 
profiles = eval(json) 
+3

这需要你完全信任json的源码 – JeffS 2012-01-15 16:27:00

+0

@JeffS你能解释一下为什么吗? – Amanda 2012-04-11 14:03:13

+4

请参阅:http://docs.python.org/library/functions.html#eval 因此,json字符串的值被解释为python代码,这意味着您允许代码作为您的程序运行,并且可能是一个主要的安全问题。 – JeffS 2012-04-11 21:20:31