OzzyW
OzzyW

Reputation: 117

TypeError: byte indices must be integers

I want to get the top artists from a specific country from the last fm API in JSON and save the name and url in the name and url variables. But it always appears "TypeError: byte indices must be integers". Do you know where is the issue?

Working example:

import requests

api_key = "xxx"     


for i in range(2,5):

    artists = requests.get('http://ws.audioscrobbler.com/2.0/?method=geo.gettopartists&country=spain&format=json&page='+str(i)+'&api_key='+api_key)
    for artist in artists:

        print(artist)

        #name = artist['topartists']['artist']['name']
        #url  = artist['topartists']['artist']['url']

Upvotes: 1

Views: 9247

Answers (1)

bruno desthuilliers
bruno desthuilliers

Reputation: 77902

You want:

response = requests.get(...)
data = response.json()
for artist in data["topartists"]["artist"]:
    name = artist["name"]
    # etc

Explanation: requests.get() returns a response object. Iterating over the response object is actually iterating over the raw textual response content, line by line. Since this content is actually json, you want to first decode it to Python (response.json() is mainly a shortcut for json.loads(response.content)). You then get a python dict with, in this case, a single key "topartists" which points to a list of "artist" dicts.

A couple hints:

First you may want to learn to use string formatting instead of string concatenation. This :

'http://ws.audioscrobbler.com/2.0/?method=geo.gettopartists&country=spain&format=json&page='+str(i)+'&api_key='+api_key

is ugly and hardly readable. Using string formatting:

urltemplate = "http://ws.audioscrobbler.com/2.0/?method=geo.gettopartists&country=spain&format=json&page={page}&api_key={api_key}"
url = urltemplate.format(page=i, api_key=api_key)

but actually requests knows how to build a querystring from a dict, so you should really use this instead:

query = {
    "method": "geo.gettopartists", 
    "country":"spain", 
    "format":"json", 
    "api_key": api_key
    }

url = "http://ws.audioscrobbler.com/2.0/"
for pagenum in range(x, y):
    query["page"] = pagenum
    response = requests.get(url, params=query)
    # etc

Then, you may also want to handle errors - there are quite a few things that can go wrong doing an HTTP request.

Upvotes: 3

Related Questions