-
-
Save TheMuellenator/c84616c21f0f9ce68c12c357d3e1c794 to your computer and use it in GitHub Desktop.
sp = spotipy.Spotify( | |
auth_manager=SpotifyOAuth( | |
scope="playlist-modify-private", | |
redirect_uri="http://example.com", | |
client_id=YOUR UNIQUE CLIENT ID, | |
client_secret= YOUR UNIQUE CLIENT SECRET, | |
show_dialog=True, | |
cache_path="token.txt" | |
) | |
) | |
user_id = sp.current_user()["id"] | |
date = input("Which year do you want to travel to? Type the date in this format YYYY-MM-DD: ") | |
song_uris = ["The list of", "song URIs", "you got by", "searching Spotify"] | |
playlist = sp.user_playlist_create(user=user_id, name=f"{date} Billboard 100", public=False) | |
# print(playlist) | |
sp.playlist_add_items(playlist_id=playlist["id"], items=song_uris) |
I'm having an error and I can't add tracks to my playlist.
raise SpotifyException(
spotipy.exceptions.SpotifyException: http status: 400, code:-1 - https://api.spotify.com/v1/playlists/6WW7HbTGZgkrOcoBL9TNDR/tracks:
Invalid track uri: spotify🧑🎨1l7ZsJRRS8wlW3WfJfPfNS, reason: NoneI had the same error and the solution was to change the argument public to False because the SCOPE on Spotify0Auth i used "playlist-modify-private", i know you fixed the problem but dont see de solution, just add thid
True!! I changed the Public = False, it worked after getting lots of errors, seems that the scope and this argument has to be the same i.e. Private
Thank you, this helped a lot!
I was not able to complete the project by myself, maybe I am too stupid, I don't know but here I found a video explaing the process to create and add songs to the playlist and it worked just fine, some of the methods used in the video are deprecated but pycharm will tell you which ones to use instead.
https://www.youtube.com/watch?v=jSOrEmKUd_c&t=2s&ab_channel=KalyanCodes
This project had nothing to do with being a good Python developer or a good web site user. This was all about trying to figure out some very badly written documenation on how to interact with Spotify. The basic Python code for working with lists and dictionaries was fine. So was the basic code for scraping a website once you knew what keys to look for. But trying to figure out the Spotify parts of this assignment were beyond my abilities. I needed help from a lot of the people on this page to finally get my code to work.
Sharing my working code below:
from bs4 import BeautifulSoup # allows us to scrape web pages and find listed items
import requests # lets us retrieve the contents of a web page
import spotipy # this tool helps us to log in and authenticate with Spotify
from spotipy.oauth2 import SpotifyOAuth
import json # lets us format some outputs for easier reading and troubleshooting
--------------------- BILLBOARD ACCESS ----------------------------------------#
date = input("Find songs from the past few decades! Type the date in this format YYYY-MM-DD: ")
this will let us pick the specific date we want to scrape
URL = f"https://www.billboard.com/charts/hot-100/{date}" # now we have the full URL for the billboard site
response = requests.get(URL) # get the HTML from billboard for the chosen date
webpage = response.text # this holds the HTML of the found page
soup = BeautifulSoup(webpage, "html.parser") # build the "object" that we are scraping
song_name_list = soup.find_all(name="h3", id="title-of-a-story", class_="a-no-trucate")
note: there were many, many classes all listed together. Just need to pick 1 that was unique to the titles
song_names = [song.getText().strip() for song in song_name_list]
The song names have lots of leading tabs, spaces and newlines, etc. So strip them off. Left with the titles only.
print(song_names)
now do the same for the artists, not really needed but good practice with scraping
artist_list = soup.find_all(name="span", class_="a-no-trucate")
artists = [artist.getText().strip() for artist in artist_list]
print(artists)
--------------------- SPOTIFY ACCESS ----------------------------------------#
You can store this in environment variables for better security
SPOTIPY_CLIENT_ID = "e31e8565affc445bb9af136de33300de"
SPOTIPY_CLIENT_SECRET = "ab32e0a155f14a7399e2f1972b5cbdf0"
SPOTIPY_REDIRECT_URI = "http://localhost:8888/callback"
Make sure you put the above URI in your Spotify developer application redirect URI, they need to match
This next line is the one that uses the credentials to get you access to Spotify. You will know it works
when you try to retrieve the userid which validates that you got into Spotify properly.
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(scope="user-library-read playlist-modify-private",
redirect_uri=SPOTIPY_REDIRECT_URI,
client_id=SPOTIPY_CLIENT_ID,
client_secret=SPOTIPY_CLIENT_SECRET,
show_dialog=False,
cache_path="token.txt"))
The above line, when executed will capture the authentication token and save it to your working directory
If the above authentication worked, you should now be able to retrieve your userid with the following query
results = sp.current_user() # this is the full dictionary. Now you can pick out your user_id
formatted_results = json.dumps(results, indent=4) # this creates a formatted view of the JSON
with open("results.json", mode="w") as file:
file.write(formatted_results) # useful if you want to see what the function returned, and in a nice format
user_id = results["id"] # query the dictionary for the "id"
print(user_id)
--------------------- Playlist URI Build ----------------------------------------#
build the URI list using the song names. You also need the year, so "split" the date on the - and keep [0]
year = date.split("-")[0]
playlist_uris = [] # want to capture all the individual uri's for the playlist in a single list
for song in song_names: # recall this from billboard, it has all the song titles
result = sp.search(q=f"track:{song} year:{year}", type="track") # this searches Spotify for the specific songs
try:
uri = result["tracks"]["items"][0]["uri"] # this builds the uri from the search results
playlist_uris.append(uri) # see if we can add the uri to our list. Will fail if nothing was found
except IndexError:
print(f"{song} doesn't exist in Spotify. Skipped.")
print(playlist_uris)
--------------------- Spotify Playlist Build ----------------------------------------#
playlist = sp.user_playlist_create(user=user_id, name=f"{date} Billboard 100", public=False)
print(playlist)
sp.playlist_add_items(playlist_id=playlist["id"], items=playlist_uris)
print(f"\nThe playlist has been created. A total of {len(playlist_uris)}/100 of the top 100 songs were found! ")
I try this code. token.txt be made and my console said it's successful process. but my spotify dashboard isn't changed. how can i solve this problem???
you need to login to spotify.com and not the developer dashboard. you will see your playlist reflected there. Hope this helps.
PLEASE I NEED HELP WHY THIS CODE DOESN'T WORK FOR ME?
import requests from bs4 import BeautifulSoup import spotipy from spotipy.oauth2 import SpotifyOAuth
CLIENT_ID = "9067a23713c34ea68d7276265816c720" CLIENT_SECRET = "334e6b70064546b092ad6b355ec171db"
url = "https://www.billboard.com/charts/hot-100/"
date = input("Which year do you want to travel to? Type the date in this Format YY-MM-DD.")
response = requests.get(f"{url}{date}") web = response.text
soup = BeautifulSoup(web, "html.parser")
musics = soup.find_all("h3", "a-no-trucate") music_titles = [] for music in musics: title = music.get_text().strip() music_titles.append(title)
sp = spotipy.Spotify( auth_manager=SpotifyOAuth( scope="playlist-modify-private", redirect_uri="http://example.com", client_id=CLIENT_ID, client_secret=CLIENT_SECRET, show_dialog=True, cache_path="token.txt" ) )
user_id = sp.current_user()["id"]
song_uris = [] year = date.split("-")[0] for song in music_titles: result = sp.search(q=f"track:{song} year:{year}", type="track") # print(result) # print("space\n\n") try: uri = result["tracks"]["items"][0] song_uris.append(uri) except IndexError: print(f"{song} doesn't exist in Spotify. Skipped.")
Creating a new private playlist in Spotify
playlist = sp.user_playlist_create(user=user_id, name=f"{date} Billboard 100", public=False) print(playlist)
Adding songs found into the new playlist
sp.playlist_add_items(playlist_id=playlist['id'], items=song_uris)
print(playlist['id'])
bro the for loop should be like this:
for song in songs_name[:100]:
song = song.get_text()
result = sp.search(q=f"track:{song} year:{year}", type="track")
print(result)
try:
If anyone needs code for this project then check below code:
import requests
from bs4 import BeautifulSoup
from dotenv import dotenv_values
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from flask import Flask, request, url_for, session, redirect
import time
# Part 2: Spotify Authentication and New Playlist Creation based on Date.
app = Flask(__name__)
secrets = dotenv_values(".env")
app.config['SESSION_COOKIE_NAME'] = secrets['SESSION_COOKIE_NAME']
app.secret_key = secrets['SPOTIFY_APP_SECRET_KEY']
TOKEN_INFO = 'token_info'
SPOTIFY_CLIENT_ID = secrets["SPOTIFY_CLIENT_ID"]
SPOTIFY_CLIENT_SECRET = secrets["SPOTIFY_CLIENT_SECRET"]
BILLBOARD_URL = secrets['BILLBOARD_URL']
date = None
if date is None:
date = input("Which year do you want to travel to? Type date in this format YYYY-MM-DD : \n\t")
time_travel_url = f"{BILLBOARD_URL}/{date}"
res = requests.get(url=time_travel_url)
res.raise_for_status()
time_travel = res.text
soup = BeautifulSoup(time_travel, "html.parser")
# data_results = soup.find_all(name="h3", id="title-of-a-story")
data_results = soup.select(selector="li ul li h3")
# print(data_results)
song_names = [(song.getText()).strip("\n\t") for song in data_results]
with open(f""
f"songs_{date}.txt", mode="w") as file:
for song in song_names:
file.write(f"{song} \n")
# all the top 100 songs name on given date
# print(song_names)
# data_songs = soup.find_all(name="h3", class_="o-chart-results-list__item")
# print(data_songs)
# songs = [song.getText() for song in data_songs]
# print(songs)
@app.route('/')
def login():
auth_url = create_spotify_oauth().get_authorize_url()
return redirect(auth_url)
@app.route('/redirect')
def redirect_page():
session.clear()
# get the authCode which needs to be exchanged to get in return auth token
code = request.args.get('code')
token_info = create_spotify_oauth().get_access_token(code=code)
session[TOKEN_INFO] = token_info
return redirect(url_for('save_to_date', _external=True))
@app.route('/saveToDate')
def save_to_date():
try:
token_info = get_token()
except:
print('User not logged in.')
return redirect('/')
# Use this return to check if our OAuth is successful.
# return 'OAuth Successful'
sp = spotipy.Spotify(auth=token_info['access_token'])
user_id = sp.current_user()['id']
current_playlists = sp.current_user_playlists()['items']
song_uris = []
# Song search to add in playlist
for song in song_names:
result = sp.search(q=f"track:{song}", type="track", market="US")
# print track: find the
# print(result['tracks']['items'][0])
try:
uri = result["tracks"]["items"][0]["uri"]
song_uris.append(uri)
except IndexError:
print(f"{song} doesn't exist in Spotify. Skipped.")
# print(song_uris)
# Check if the playlist already exist for given date:
billboard_100_playlist_id = None
for playlist in current_playlists:
if playlist['name'] == f'{date} Billboard 100':
billboard_100_playlist_id = playlist['id']
if not billboard_100_playlist_id:
new_playlist = sp.user_playlist_create(user_id, f'{date} Billboard 100', True)
billboard_100_playlist_id = new_playlist['id']
# return f"Billboard top 100 playlist id for date {date} is not found."
# Now use this playlist to add all the song uris:
sp.playlist_add_items(billboard_100_playlist_id, song_uris, None)
print(f"All the songs from timeline {date} added to the playlist '{date} Billboard 100' in spotify.")
return f"All the songs from timeline {date} added to the playlist '{date} Billboard 100' in spotify."
def get_token():
token_info = session.get(TOKEN_INFO, None)
if not token_info:
redirect(url_for('login', _external=False))
now = int(time.time())
is_expired = token_info['expires_at'] - now < 60
if is_expired:
spotify_oauth = create_spotify_oauth()
token_info = spotify_oauth.refresh_access_token(token_info['refresh_token'])
# return token info if not expired & if expired then refreshed before sending the given token info.
return token_info
def create_spotify_oauth():
return SpotifyOAuth(
client_id=SPOTIFY_CLIENT_ID,
client_secret=SPOTIFY_CLIENT_SECRET,
redirect_uri=url_for('redirect_page', _external=True),
scope='user-library-read playlist-modify-public playlist-modify-private'
)
app.run(debug=False)
Is anyone else finding this project challenging? I'm having trouble grasping the concepts involved. Any help or clarification would be greatly appreciated
#Here Is The Complete Project In Simplest Way
from bs4 import BeautifulSoup
import requests
import spotipy
from spotipy.oauth2 import SpotifyOAuth
#date=input("Please Enter date in YYYY-MM- Format")
response=requests.get("https://www.billboard.com/charts/hot-100/2023-08-05/")
soup=BeautifulSoup(response.text,"html.parser")
all_titles= soup.select(selector=".o-chart-results-list__item #title-of-a-story")
client_id="05d82555b91a4325b5e1e5563e4b0faa"
client_secret="5c3d0bc4a04d47b38935ee977742c379"
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=client_id,
client_secret=client_secret,
redirect_uri='https://example.com',
scope='playlist-modify-private'))
user_profile = sp.current_user()
Extract user ID from the profile
user_id = user_profile['id']
print(user_id)
playlist_name = 'Top 100 Songs'
playlist_description = 'Your Playlist Description'
playlist = sp.user_playlist_create(user=user_id, name=playlist_name, public=False, description=playlist_description)
for titles in all_titles:
print(titles.getText().strip())
# Search for the song
song_title = titles.getText().strip()
search_results = sp.search(q=song_title, type='track')
# Extract the track URI
track_uri = search_results['tracks']['items'][0]['uri'] # Assuming the first search result is the desired song
playlist_id = playlist['id']
sp.playlist_add_items(playlist_id=playlist_id, items=[track_uri])
Here is my code, this one is definitely challenging because the documentation is not explained very well (at least for me) so it requires trials and lots of errors. Worked it all out in the end. Hope this helps
from bs4 import BeautifulSoup
import requests
import spotipy
from spotipy.oauth2 import SpotifyOAuth
time_input = input("Enter the time you want to jump to in this format YYYY-MM-DD: ")
URL = "https://www.billboard.com/charts/hot-100/"+time_input
TEMP1 = "c-title a-no-trucate a-font-primary-bold-s u-letter-spacing-0021 lrv-u-font-size-18@tablet lrv-u-font-size-16 u-line-height-125 u-line-height-normal@mobile-max a-truncate-ellipsis u-max-width-330 u-max-width-230@tablet-only"
TEMP2 = "c-title a-no-trucate a-font-primary-bold-s u-letter-spacing-0021 u-font-size-23@tablet lrv-u-font-size-16 u-line-height-125 u-line-height-normal@mobile-max a-truncate-ellipsis u-max-width-245 u-max-width-230@tablet-only u-letter-spacing-0028@tablet"
TEMP3 = "c-label a-no-trucate a-font-primary-s lrv-u-font-size-14@mobile-max u-line-height-normal@mobile-max u-letter-spacing-0021 lrv-u-display-block a-truncate-ellipsis-2line u-max-width-330 u-max-width-230@tablet-only"
TEMP4 = "c-label a-no-trucate a-font-primary-s lrv-u-font-size-14@mobile-max u-line-height-normal@mobile-max u-letter-spacing-0021 lrv-u-display-block a-truncate-ellipsis-2line u-max-width-330 u-max-width-230@tablet-only u-font-size-20@tablet"
# These are classes scrapped from the billboard website
CLIENT_ID = (your client_id here)
CLIENT_SECRET = (your client_secret here)
REDIRECT_URI = "http://example.com"
SPOTIFY_URL = "https://api.spotify.com/v1"
USERNAME = (your username here)
# ------------- SCRAPE BILLBOARD AND GET 2 LISTS OF SONGS AND CORRESPONDING ARTISTS -------------
response = requests.get(URL)
data = response.text
soup = BeautifulSoup(data, "html.parser")
songs = [item.getText().strip() for item in soup.find_all(name="h3", id="title-of-a-story", class_=TEMP1)]
first_song = soup.find(name="h3", id="title-of-a-story", class_=TEMP2).getText().strip()
songs.insert(0, first_song)
artists = [item.getText().strip() for item in soup.find_all(name="span", class_=TEMP3)]
first_artist = soup.find(name="span", class_=TEMP4).getText().strip()
artists.insert(0, first_artist)
# ------------- ACCESS SPOTIFY AND MAKE AUTH -------------
scope = "playlist-modify-private"
sp = spotipy.Spotify(
auth_manager=SpotifyOAuth(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
cache_path="token.txt",
scope=scope,
show_dialog=True,
username=USERNAME,
)
)
user_id = sp.current_user()["id"]
# ------------- CREATE PLAYLIST -------------
playlist = sp.user_playlist_create(
user=user_id,
name="Top 100 Billboard songs",
public=False,
collaborative=False,
description=f"Top 100 Billboard songs on {time_input}",
)
playlist_id = playlist["id"]
# ------------- SEARCH FOR SONGS -------------
class NoSongFound(Exception):
pass
uris = []
for index in range(0, len(songs)):
try:
search = sp.search(
q=f"track:{songs[index]} artist:{artists[index]}",
limit=1,
offset=0,
market=None,
type="track",
)
if search["tracks"]["total"] == 0:
raise NoSongFound
except NoSongFound:
pass
else:
uri = str(search["tracks"]["items"][0]["id"])
uris.append(uri)
# ------------- ADD SONGS -------------
sp.playlist_add_items(playlist_id=playlist_id, items=uris)
print(sp.playlist_items(
playlist_id=playlist_id,
additional_types="track",
))
Hey guys, I keep getting an insufficient client scope error. What am I still missing in the code?
Also, when I run Angela's code it creates the playlist but can't add any songs. I am a bit lost there lol.
Hey guys, I keep getting an insufficient client scope error. What am I still missing in the code?
Also, when I run Angela's code it creates the playlist but can't add any songs. I am a bit lost there lol.
@bluebanana18 I was having the exact same issue.
The solution for me was updating the scope in the Spotify Authentication section to include both private and public playlist-modify scopes. (update to line 3 of Angela's code)
Yes, this seems counter intuitive since on line 15 of the example, the created playlist is set as private and has the playlist-modify-private scope set, so you think it would work. But looks like the Spotify API wants both scopes set.
Also you may need to delete your token.txt file before running in order for the token to reset properly.
Example:
sp = spotipy.Spotify(
auth_manager=SpotifyOAuth(
scope="playlist-modify-private playlist-modify-public",
redirect_uri="http://example.com",
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
show_dialog=True,
cache_path="token.txt"
)
)
Hope this helps
@drakewilcox
Mind blown. It was really that simple, huh. Thanks a lot!
Here is my code, it is working perfectly, I had to have a little bit of hand holding from chat gpt
import requests
from bs4 import BeautifulSoup
import spotipy
from spotipy.oauth2 import SpotifyOAuth
Set your Spotify app credentials
You will need to make a spotify web app to get this data, go to spotify dev tools
SPOTIPY_CLIENT_ID = 'YOUR CLIENT ID'
SPOTIPY_CLIENT_SECRET = 'YOUR CLIENT SECRET'
SPOTIPY_REDIRECT_URI = 'YOUR REDIRECT URI'
SCOPE = 'playlist-modify-public user-read-private'
date = input("What date would you like to travel back in time to? YYYY-MM-DD")
endpoint = f"https://www.billboard.com/charts/hot-100/{date}/"
Scrape web for top 100 songs
response = requests.get(endpoint)
html_data = response.text
soup = BeautifulSoup(html_data, "html.parser")
songs = soup.select("li ul li h3")
songs_titles = [song.getText().strip() for song in songs]
track_uris = []
Authenticate with Spotify
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIPY_CLIENT_ID,
client_secret=SPOTIPY_CLIENT_SECRET,
redirect_uri=SPOTIPY_REDIRECT_URI,
scope=SCOPE))
Find track URIs
for song in songs_titles:
try:
results = sp.search(q=f"track:{song}", type="track")
track_uri = results['tracks']['items'][0]['uri']
track_uris.append(track_uri)
except IndexError:
continue
# Authenticate with Spotify
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIPY_CLIENT_ID,
client_secret=SPOTIPY_CLIENT_SECRET,
redirect_uri=SPOTIPY_REDIRECT_URI,
scope=SCOPE))
Get current user's profile data
user_id = sp.current_user()['id']
Create a new playlist for the current user
playlist_name = f"Billboard top songs on {date}"
playlist_description = "Created with Python"
playlist = sp.user_playlist_create(user=user_id, name=playlist_name, description=playlist_description)
Get the playlist ID
playlist_id = playlist['id']
Add tracks to the playlist
sp.playlist_add_items(playlist_id=playlist_id, items=track_uris)
print(f"Playlist created and tracks added. Playlist ID: {playlist_id}")
# Use this return to check if our OAuth is successful. # return 'OAuth Successful' sp = spotipy.Spotify(auth=token_info['access_token']) user_id = sp.current_user()['id'] current_playlists = sp.current_user_playlists()['items'] song_uris = [] # Song search to add in playlist for song in song_names: result = sp.search(q=f"track:{song}", type="track", market="US") # print track: find the # print(result['tracks']['items'][0]) try: uri = result["tracks"]["items"][0]["uri"] song_uris.append(uri) except IndexError: print(f"{song} doesn't exist in Spotify. Skipped.") # print(song_uris) # Check if the playlist already exist for given date: billboard_100_playlist_id = None for playlist in current_playlists: if playlist['name'] == f'{date} Billboard 100': billboard_100_playlist_id = playlist['id'] if not billboard_100_playlist_id: new_playlist = sp.user_playlist_create(user_id, f'{date} Billboard 100', True) billboard_100_playlist_id = new_playlist['id'] # return f"Billboard top 100 playlist id for date {date} is not found."
Awesome work. However, I am having trouble carrying out the playlist check. I cannot retrieve any information running the line below immediately after the authentication steps. I can print out user_id = sp.current_user()["id"] without any problem.
Can you shed some light on what should i do?
current_playlists = sp.current_user_playlists()['items']
After 5 days shaking my brain. I can create playlist, add items. But stills struggling authenticate and search songs, can't find any clue between solution and documentation. Maybe my English is not good enough, or spotipy documentation too hard to understand?
I should spend a few days to review lesson.
After Executing the above code , i am getting below error
urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)
from bs4 import BeautifulSoup
import requests
import spotipy
from spotipy.oauth2 import SpotifyOAuth
# Replace these with your actual Spotify API credentials
CLIENT_ID = "your_client_id"
SECRET_KEY = "your_secret_key"
REDIRECT_URI = "http://example.com" # Use your desired redirect URI
# Scraping Billboard 100
date = input("Which year do you want to travel to? Type the date in this format YYYY-MM-DD: ")
response = requests.get(f"https://www.billboard.com/charts/hot-100/{date}")
soup = BeautifulSoup(response.text, 'html.parser')
song_names_spans = soup.select("li ul li h3")
song_names = [song.getText().strip() for song in song_names_spans]
# Spotify Authentication
sp = spotipy.Spotify(
auth_manager=SpotifyOAuth(
scope="playlist-modify-private",
redirect_uri=REDIRECT_URI,
client_id=CLIENT_ID,
client_secret=SECRET_KEY,
show_dialog=True,
cache_path="token.txt"
)
)
user_id = sp.current_user()["id"]
# Searching Spotify for songs by title
song_uris = []
year = date.split("-")[0]
for song in song_names:
result = sp.search(q=f"track:{song} year:{year}", type="track")
if result["tracks"]["items"]:
uri = result["tracks"]["items"][0]["uri"]
song_uris.append(uri)
else:
print(f"{song} doesn't exist in Spotify. Skipped.")
# Creating a new private playlist in Spotify
playlist = sp.user_playlist_create(user=user_id, name=f"{date} Billboard 100", public=False)
print(f"Playlist created: {playlist['name']}")
print(playlist)
# Adding songs found into the new playlist
sp.playlist_add_items(playlist_id=playlist["id"], items=song_uris)
print(f"{len(song_uris)} songs added to the playlist.")
****
export CLIENT_ID='your-spotify-client-id'
export CLIENT_SECRET='your-spotify-client-secret'
export REDIRECT_URI='your-app-redirect-url'
****
As non native speaker I'm struggling everyday, feeling stupid anytime sit at front of computer. Spend 400 days just to learn 50% of the course... But I guess that's the path I must take.
This lesson alone took me more than 10 days just to understand the solution lol.
So I made a video step by step how to write the code based on the solution. Hope this will save some time for anyone who not really good at English like me.
https://www.youtube.com/watch?v=Oxph5K23_5w
After Executing the above code , i am getting below error
urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1091)
If you're done but yet your playlist doesn't reflect try using http://localhost:8888/callback as your Redirect url in both your code and your spotify developer setting
REDIRECT_URI = "http://localhost:8888/callback"
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
scope="playlist-modify-private"
))
Step 4: Get the current user ID
user = sp.current_user()
user_id = user['id']
Step 5: Create a new Spotify playlist
playlist_name = f"Billboard Hot 100 - {date}"
playlist_description = f"Top 100 songs on Billboard for {date}"
new_playlist = sp.user_playlist_create(user=user_id, name=playlist_name, description=playlist_description, public=False)
print(f"Created Playlist: {new_playlist['name']} (ID: {new_playlist['id']})")
Step 6: Search for each song on Spotify and add to the playlist
track_uris = []
for song in song_titles:
result = sp.search(q=f"track:{song}", type="track", limit=1)
try:
track_uri = result['tracks']['items'][0]['uri']
track_uris.append(track_uri)
except IndexError:
print(f"{song} not found on Spotify. Skipping.")
Add all found tracks to the playlist
if track_uris:
sp.playlist_add_items(playlist_id=new_playlist['id'], items=track_uris)
print(f"Added {len(track_uris)} songs to the playlist.")
else:
print("No songs were added to the playlist.")
This is my version and it works for me having as an end result adding a playlist to my Spotify account.
mport spotipy
from spotipy.oauth2 import SpotifyOAuth
import requests
from bs4 import BeautifulSoup
from dotenv import load_dotenv
import os
import pprint
Top 100 songs travel to memory lane
year_to_travel = input("What year would you like to travel? Please type the date on this format YYYY-MM-DD\n")
url = f"https://www.billboard.com/charts/hot-100/{year_to_travel}"
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0"
}
response = requests.get(url=url, headers=header)
soup = BeautifulSoup(response.content, "html.parser")
print(soup.prettify())
with open("page_to_check.html", "w", encoding='utf-8') as file:
file.write(str(soup))
song_names_spans = soup.select("li ul li h3")
print(song_names_spans)
using a list comprehension
songs_names_list = [song.getText().strip() for song in song_names_spans]
print(songs_names_list)
load_dotenv('.env')
CLIENT_ID = os.getenv("SPOTIPY_CLIENT_ID")
CLIENT_SECRET = os.getenv("SPOTIPY_CLIENT_SECRET")
REDIRECT_URI = os.getenv("SPOTIPY_REDIRECT_URI")
OAUTH_AUTHORIZE_URL = 'https://accounts.spotify.com/authorize'
OAUTH_TOKEN_URL = 'https://accounts.spotify.com/api/token'
scope = "playlist-modify-private", "Playlist-modify_public"
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=REDIRECT_URI,
scope="playlist-modify-private",
show_dialog=True,
cache_path="token.txt",
))
track_uris = []
for song_name in songs_names_list:
results = sp.search(q=song_name, type="track", limit=1)
tracks = results.get('tracks', {}).get('items', [])
# print(results)
try:
track_uri = tracks[0]["uri"]
track_uris.append(track_uri)
except IndexError:
print(f"{song_name} doesn't exist in Spotify. Skipped.")
pprint.pp(track_uris)
Create a private playlist
User_id = sp.current_user()["id"]
playlist_name = "My Python Playlist(Songs Names Only)"
playlist = sp.user_playlist_create(user=User_id, name=playlist_name, public=False)
pprint.pp(playlist)
add tracks to the playlist
if track_uris:
sp.playlist_add_items(playlist_id=playlist['id'], items=track_uris)
print(f"Playlist'{playlist_name}'has been created successfully!")
else:
print("No valid tracks found. Playlist not created")

billboard site is not responding. pls help
I had to add very specified search criteria when fetching information from Billboard site:
song_names_spans = soup.select("ul li ul li h3", id_="title-of-a-story", class_="c-title")
v-- I also had issue creating the playlist to Spotify. Code below resolved my issue, thank you @grizzleswens ! --v
grizzleswens commented on Mar 5, 2024
Here is my code, it is working perfectly, I had to have a little bit of hand holding from chat gptimport requests from bs4 import BeautifulSoup import spotipy from spotipy.oauth2 import SpotifyOAuth
Set your Spotify app credentials
You will need to make a spotify web app to get this data, go to spotify dev tools
SPOTIPY_CLIENT_ID = 'YOUR CLIENT ID' SPOTIPY_CLIENT_SECRET = 'YOUR CLIENT SECRET' SPOTIPY_REDIRECT_URI = 'YOUR REDIRECT URI' SCOPE = 'playlist-modify-public user-read-private'
date = input("What date would you like to travel back in time to? YYYY-MM-DD") endpoint = f"https://www.billboard.com/charts/hot-100/{date}/"
Scrape web for top 100 songs
response = requests.get(endpoint) html_data = response.text
soup = BeautifulSoup(html_data, "html.parser")
songs = soup.select("li ul li h3") songs_titles = [song.getText().strip() for song in songs]
track_uris = []
Authenticate with Spotify
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIPY_CLIENT_ID, client_secret=SPOTIPY_CLIENT_SECRET, redirect_uri=SPOTIPY_REDIRECT_URI, scope=SCOPE))
Find track URIs
for song in songs_titles: try: results = sp.search(q=f"track:{song}", type="track") track_uri = results['tracks']['items'][0]['uri'] track_uris.append(track_uri) except IndexError: continue
# Authenticate with Spotify
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(client_id=SPOTIPY_CLIENT_ID, client_secret=SPOTIPY_CLIENT_SECRET, redirect_uri=SPOTIPY_REDIRECT_URI, scope=SCOPE))
Get current user's profile data
user_id = sp.current_user()['id']
Create a new playlist for the current user
playlist_name = f"Billboard top songs on {date}" playlist_description = "Created with Python" playlist = sp.user_playlist_create(user=user_id, name=playlist_name, description=playlist_description)
Get the playlist ID
playlist_id = playlist['id']
Add tracks to the playlist
sp.playlist_add_items(playlist_id=playlist_id, items=track_uris)
print(f"Playlist created and tracks added. Playlist ID: {playlist_id}")
To add the tracks to the playlist I used another spotipy method, I can't find the one in the solution in the documentation. According to PyCharm that method also doesn't exist. Here is my code I used:
``
import requests
from bs4 import BeautifulSoup
import spotipy
from spotipy.oauth2 import SpotifyOAuth
import os
from dotenv import load_dotenv
load_dotenv()
BILLBOARD_ENDPOINT= "https://www.billboard.com/charts/hot-100/"
BILLBOARD_HEADER = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:131.0) Gecko/20100101 Firefox/131.0"}
# entered a fixed date for testing purposes
# date = input("Which year do you want to travel to? Type the date in this format YYYY-MM-DD:")
date = "2022-12-12"
response = requests.get(url=f"{BILLBOARD_ENDPOINT}{date}",headers=BILLBOARD_HEADER)
soup = BeautifulSoup(response.text, "html.parser")
songs = soup.find_all(name="h3", class_="c-title a-no-trucate a-font-primary-bold-s u-letter-spacing-0021 lrv-u-font-size-18@tablet lrv-u-font-size-16 u-line-height-125 u-line-height-normal@mobile-max a-truncate-ellipsis u-max-width-330 u-max-width-230@tablet-only")
top_100_songs = []
for song in songs:
title = song.getText().strip()
top_100_songs.append(title)
sp = spotipy.Spotify(
auth_manager=SpotifyOAuth(
scope="playlist-modify-private",
redirect_uri="http://example.com",
client_id=os.environ["SPOTIPY_CLIENT_ID"],
client_secret=os.environ["SPOTIPY_CLIENT_SECRET"],
show_dialog=True,
cache_path="token.txt",
username="***********"
)
)
user_id = sp.current_user()["id"]
track_uri_list = []
for song in top_100_songs:
search = sp.search(q=song,type="track")
try:
track_uri_list.append(search["tracks"]["items"][0]["uri"])
except IndexError:
print("Track not found")
playlist_name = f"{date} Billboard 100"
playlist = sp.user_playlist_create(user_id, playlist_name, public=False, description=f"Billboard top 10 from {date}")
playlist_id = playlist["id"]
print(f"playlist created with id {playlist_id}")
sp.user_playlist_add_tracks(user=user_id, playlist_id=playlist_id, tracks=track_uri_list)
print("tracks added")
``
Found a helpful fix for error handling. If you query without the "track:", "artist:" or "year:" keywords, it does a basic search and pulls the most relevant. I also removed the parentheses from any song title. Haven't gotten any errors so far.