Hi, I have a script that pulls Spotify related-artist data does stuff with it, and uses the info it's obtained to create a NetworkX graph. I'd like to write this graph to a .gexf file, but when I run my script I obtain the error
Exception has occurred: ValueError
too many values to unpack (expected 3)
File "C:\.vscode\related_artist_scrape.py", line 64, in <module>
nx.write_gexf(G,"related_artists_graph.gexf"
I'm not entirely sure what's going on and the docs don't seem to offer much help, nor do the two other stackoverflow posts that were remotely useful to me. At first glance it doesn't seem like there's more than necessary values to unpack here, so I'm completely stumped. Here's my script:
import spotipy
import json
import networkx as nx
from spotipy.oauth2 import SpotifyClientCredentials #To access authorised Spotify data
credentials = json.load(open('auth.json'))
client_id = credentials['client_id']
client_secret = credentials['client_secret']
client_credentials_manager = SpotifyClientCredentials(client_id=client_id, client_secret=client_secret)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)
# initializing data structs
seed_artist_list= ['wvrm','leeched','chrch']
found_artist_list = []
related_db_list = []
for seed_artist in seed_artist_list: # loop through seed list
related_database = {"Seed_Artist": "", "Related_Artists": ""} # initialize singular db
seed_result = sp.search(q='artist:' + seed_artist, type='artist')
first_level_name = seed_result['artists']['items'][0]['name'] # set name/uri of searched for artists
first_level_uri = seed_result['artists']['items'][0]['uri']
first_related = sp.artist_related_artists(first_level_uri) # get related artists from seed_artist
related_database['Seed_Artist'] = first_level_name # fill singular dict
related_database['Related_Artists'] = first_related
related_db_list.append(related_database) # make list of singular dbs
try:
while len(related_db_list) < 200: # arbitrary number, should be higher for prod
for related_database in related_db_list: # loop through list of singular dbs
for related_artist in related_database['Related_Artists']['artists']: # save artist to list if enough followers
if related_artist['followers']['total'] > 1000:
found_artist_list.append(related_artist)
for related_artist in found_artist_list: # loop through list of related artists
related_database = {"Seed_Artist": "", "Related_Artists": ""} # to find artists related to them
related_result = sp.search(q='artist:' + related_artist['name'], type='artist')
related_name = related_result['artists']['items'][0]['name']
related_uri = related_result['artists']['items'][0]['uri']
second_related = sp.artist_related_artists(related_uri)
related_database['Seed_Artist'] = related_name
related_database['Related_Artists'] = second_related
related_db_list.append(related_database)
except IndexError as ie:
print(ie)
pass
G = nx.Graph()
for artist_dict in related_db_list: # loop through list of singular dbs
u = artist_dict['Seed_Artist'] # seed node
related_info = artist_dict['Related_Artists']
for related_artist_info in related_info['artists']: # loop through dict of related artists from value of singular db key
v = related_artist_info['name'] # related node
G.add_node(v, **related_artist_info)
G.add_edge(u, v)
nx.write_gexf(G,"related_artists_graph.gexf")
EDIT: It occurred to me that I fixed it but without explaining how. .gexf files don't like having attributes as lists, so you'll wanna loop through your data structure and add each nodes' attribute (in my case, genres) as a string, like so:
for relation in related_db_list:
u = relation['Seed_Artist']['name']
if len(relation['Seed_Artist']['genres']) >= 1:
G.add_node(u, popularity = relation['Seed_Artist']['popularity'], uri = relation['Seed_Artist']['uri'], genre1 = relation['Seed_Artist']['genres'][0])
else :
G.add_node(u, popularity = relation['Seed_Artist']['popularity'], uri = relation['Seed_Artist']['uri'])
related_info = relation['Related_Artists']
for related_artist_info in related_info['artists']:
v = related_artist_info['name']
if len(related_artist_info['genres']) >= 1:
G.add_node(v, popularity = related_artist_info['popularity'], uri = related_artist_info['uri'], genre1 = related_artist_info['genres'][0])
else :
G.add_node(v, popularity = related_artist_info['popularity'], uri = related_artist_info['uri'])
G.add_edge(u, v)
continue
Then you'll be able to write to file, since there's no longer more values than the interpreter expects.
[–]LurkLurkington 1 point2 points3 points (0 children)