4

Writing a Spotipy script to return album tracks from a given album I'm occasionally getting the error:

    album_id = results["albums"]["items"][0]["uri"]
IndexError: list index out of range

The error tends to happen for more popular artists looping over all of their albums. I'm guessing results list has either reached it's limit or it's getting out of sequence somehow. Either way I'm not sure how to fix it as I'm pretty sure I got the album_id line off the Spotipy website. Any ideas?

#!/usr/bin/python
# -*- coding: utf-8 -*-

import spotipy

sp = spotipy.Spotify()
sp.trace = False


def get_artist_albums(artist):
  results = sp.search(q = "artist:" + artist, type = "artist")
  items = results["artists"]["items"]
  artist = items[0]
  # print artist

  albums = []
  albumsTitles  = []
  results = sp.artist_albums(artist["id"], album_type = "album")
  albums.extend(results["items"])
  while results["next"]:
    results = sp.next(results)
    albums.extend(results["items"])
  seen = set() # to avoid dups
  albums.sort(key = lambda album:album["name"].lower())

  for album in albums:
    albumTitle = album["name"]
    if albumTitle not in seen:
      print((" " + albumTitle))
      seen.add(albumTitle)
      albumsTitles.append(albumTitle)

  # return albumsTitles
  return albumsTitles 

def get_albums_tracks(album):
  albumtracks = []

  results = sp.search(q = "album:" + album, type = "album")

  # get the first album uri
  album_id = results["albums"]["items"][0]["uri"]

  # get album tracks
  tracks = sp.album_tracks(album_id)
  c = 1
  # print album
  for track in tracks["items"]:
    # print "#%s %s" %(c, track["name"])
    albumtracks.append(track["name"])
    c +=1
  return albumtracks


# 3 album band - ok
phosgoreAlbums = get_artist_albums("Phosgore")
for item in phosgoreAlbums:
  print get_albums_tracks(item)
  print ""

# 6 album band - ok
# (well technically 2, but's let not get into that night now)
joyDivisionAlbums = get_artist_albums("Joy Division")
for item in joyDivisionAlbums:
  print get_albums_tracks(item)
  print ""

# 34 albums - falls over
cherAlbums = get_artist_albums("Cher")
for item in cherAlbums:
  print get_albums_tracks(item)
  print ""

# 38 album band - falls over
theCureAlbums = get_artist_albums("The Cure")
for item in theCureAlbums:
  print get_albums_tracks(item)
  print ""

# 43 album band - falls over
aliceCooperAlbums = get_artist_albums("Alice Cooper")
for item in aliceCooperAlbums:
  print get_albums_tracks(item)
  print ""
Ghoul Fool
  • 6,249
  • 10
  • 67
  • 125
  • Could you provide a sample artist+album combination for which it fails? Or, is it non-deterministic? – alecxe Sep 25 '16 at 15:06
  • @alecxe I've updated the code with a few statistics. I does seem to be a little on the random side -which doesn't help much – Ghoul Fool Sep 26 '16 at 19:53
  • What if you add intermediate artificial delays between the requests - does it help to bring the failure rate down?.. – alecxe Sep 26 '16 at 20:00
  • @alecxe slowing down the count (time.sleep(1)) had no effect – Ghoul Fool Sep 27 '16 at 19:00
  • @Martijn Pieters♦ That worked brilliantly, thank you! Spotify has Alice Copper, Theatre of Death: Live At Hammersmith 2009 as having no tracks - who knew? Bad Spotify, no biscuit. – Ghoul Fool Sep 27 '16 at 19:03

1 Answers1

3

results["albums"]["items"] is simply an empty list, so there is no element at index 0. You could test for that before trying to index into it:

if not results["albums"]["items"]:
    # no albums found, so no tracks either
    return []

album_id = results["albums"]["items"][0]["uri"]
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343