2012-10-31 42 views
1

我目前有一个脚本,应该获取并返回Bit.ly链接所具有的点击次数。我开始通过收集和阅读来自Bitly网址的数据,我似乎做得很对。为什么我得到一个IndexError(看似)正确拆分的字符串?

bitly_data = "https://api-ssl.bitly.com/v3/link/clicks?access_token=ACCESS_TOKEN&link=http://bit.ly/"+link 
    src = urllib2.urlopen(bitly_data) 
    src = src.read() 

linkTY8lnd这样的东西,src是一个字符串,看起来像

{"status_code": 200, "data": {"units": -1, "tz_offset": -4, "unit": "day", "link_clicks": 535}, "status_txt": "OK"}

我现在要分析此字符串得到公正link_clicks后的数值。我认为做这件事的最好方法是分两次。

src=src.split('clicks": ') 
    src = str(src[1]) 
    clicks = src.split('}, "status') 
    clicks = clicks[0] 

当我运行这个时,点击确实最终等于正确的数字,只有这个数字。但是,终端返回src = str(src[1])行的IndexError。我试图摆脱str()但这没有效果。不知道为什么我得到这个错误,尽管最终值被纠正,我们将不胜感激。

这里是全部回溯:

Traceback (most recent call last): 
    File "/Library/Python/2.7/site-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1701, in __call__ 
    return self.wsgi_app(environ, start_response) 
    File "/Library/Python/2.7/site-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1689, in wsgi_app 
    response = self.make_response(self.handle_exception(e)) 
    File "/Library/Python/2.7/site-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1687, in wsgi_app 
    response = self.full_dispatch_request() 
    File "/Library/Python/2.7/site-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1360, in full_dispatch_request 
    rv = self.handle_user_exception(e) 
    File "/Library/Python/2.7/site-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1358, in full_dispatch_request 
    rv = self.dispatch_request() 
    File "/Library/Python/2.7/site-packages/Flask-0.9-py2.7.egg/flask/app.py", line 1344, in dispatch_request 
    return self.view_functions[rule.endpoint](**req.view_args) 
    File "/Users/Zach/Dropbox/bitly/bit.py", line 35, in settings 
    src = str(src[1]) 
IndexError: list index out of range 

预先感谢您。

回答

6

这个响应是json,因此,解码json而不是试图解析字符串。

>>> import json 
>>> resp = '{"status_code": 200, "data": {"units": -1, "tz_offset": -4, "unit": "day", "link_clicks": 535}, "status_txt": "OK"}' 
>>> resp_object = json.loads(resp) 
>>> resp_object and resp_object.get('data', {}).get('link_clicks', 0) or 0 
535 
+0

谢谢你的快速帮帮我!然而,按照你的指示,我似乎正在得到一个TypeError:''TypeError:'NoneType'对象不是可以下载的,尽管同样返回正确的点击次数。 – zch

+0

提供正在执行此操作的代码。如果你得到了一个'TypeError'但仍然得到一个值,那么你正在运行多个请求或其他奇怪的事情。如果你有'None'来代替有效的对象,那么你就不会有点击。 – sberry

+0

如果你在resp_object中得到None,那么你可以明确地检查它,或者像上面的最后一行更新那样更新,并且None情况以及缺少'data'或'link_clicks'应该至少显示'0 '因此。 – sberry

0

你可以试试这个,找出link_clicks值,使用ast.literal_eval()

In [14]: import ast 

In [15]: src=`{"status_code": 200, "data": {"units": -1, "tz_offset": -4, "unit": "day", "link_clicks": 535}, "status_txt": "OK"}` 

In [16]: d=ast.literal_eval(src) 

In [17]: d["data"]["link_clicks"] 
Out[17]: 535 
+0

如果你不信任'literal_eval'会证明是非常危险的你是'eval'的字符串 – inspectorG4dget

+2

@ inspectorG4dget我认为它是'eval()',这被认为是危险的。正如文档所言:“这可以用于安全地评估包含来自不受信任来源的Python表达式的字符串,而不需要自己解析这些值。”# http://docs.python.org/2/library/ast.html#ast.literal_eval –

+0

'literal_eval'只能证明简单的类型,所以没有真正的危险,但我不相信(也可能是错误的),所有的json总是以这种方式解析,如果不是这样,这种方法很可能产生某些时候有例外。 – sberry

2

src看起来像它的JSON。为什么不使用json模块直接读取它?

无论出于何种原因,如果你不希望使用json,然后阅读:

错误是由你假定你分割的子拆分字符串中的存在,即'clicks": '确实引起子字符串为src。如果不是这种情况(因为我怀疑它不是当错误发生时),那么split返回一个只有一个元素的列表,该元素是src

如果您希望在这种情况下,src[1]应该调用src = src.split('clicks": ')后给你一个空字符串,那么你最好使用str.partition

In [5]: somestr = 'prefixclicks: "suffix' 

In [6]: somestr.partition('clicks: "') 
Out[6]: ('prefix', 'clicks: "', 'suffix') 

In [7]: somestr.partition('clicks: "')[-1] 
Out[7]: 'suffix' 

In [8]: somestr = 'prefixsuffix' 

In [9]: somestr.partition('clicks: "') 
Out[9]: ('prefixsuffix', '', '') 

In [10]: somestr.partition('clicks: "')[-1] 
Out[10]: '' 

希望这有助于

相关问题