简体   繁体   中英

Why am I getting an IndexError for a (seemingly) properly-split string?

I currently have a script that is supposed to fetch and return the number of clicks a Bit.ly link has. I start out by gathering and reading the data from a Bitly url, which I appear to be doing correctly.

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

When link is something such as TY8lnd , src is a string that looks something like

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

I now want to parse this string to get just the numerical value after link_clicks . I figured the best way to do this was by making two splits.

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

When I run this, clicks does, ultimately, equal the correct number and only that. However, Terminal returns an IndexError for the line src = str(src[1]) . I tried getting rid of the str() but this had no effect. An understanding as to why I am getting this error despite the end value being corrected would be greatly appreciated.

Here is the Traceback in its entirety:

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

Thank you in advance.

This response is json, as such, decode the json instead of trying to parse the string.

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

src looks like it's JSON. Why not use the json module to read it directly?

For whatever reason if you don't want to use json , then read on:

The error is caused by you assuming that the substring you split on exists in the string you split, ie that 'clicks": ' is indeed a substring of src . If this is not the case (as I suspect it isn't when the error is raised), then split returns a list with only one element in it, and that element is src .

If you prefer that in this case, that src[1] should give you an empty string after calling src = src.split('clicks": ') , then you are better off using 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]: ''

Hope this helps

you can try this to find out the value of link_clicks , use 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM