Spotify Playlist Generator.

Automatically create Spotify playlist for Billboard Top100 Songs

In this article, we will discuss how to build a web application using Flask, BeautifulSoup, and the Spotipy library to automatically create Spotify playlists for the Billboard Top 100 songs of a specific date.

Among music fans in the World, the Billboard Charts are widely recognized for determining song popularity. Many music enthusiasts enjoy listening to the top songs of a particular date to reminisce about the past or discover new music. However, manually creating a playlist for the Billboard Top 100 songs can be time-consuming. To automate this process, we can leverage web scraping techniques to extract the song information from the Billboard website and use the Spotify API to search for and create a playlist of these songs.

Technologies Used:

  • Flask: A lightweight web framework in Python for building web applications.

  • BeautifulSoup: A Python library for parsing HTML and XML documents, which we will use to scrape song information from the Billboard website.

  • Spotipy: A Python library for the Spotify Web API, which allows us to search for songs and create playlists.

  • dotenv: A Python library for loading environment variables from a .env file.

Project Setup:

Let's start by setting up the project. Create a new directory and initialize a virtual environment using your preferred method. Then, install the required libraries using pip:

pip install flask beautifulsoup4 spotipy python-dotenv

Next, create a new Python file called app.py and import the necessary modules:

from flask import Flask, render_template, request
import requests
from bs4 import BeautifulSoup
import spotipy
from spotipy.oauth2 import SpotifyOAuth
from dotenv import dotenv_values, load_dotenv

We will also create an instance of the Flask application:

app = Flask(__name__)
load_dotenv(".env")
env_vars = dotenv_values(".env")

Web Scraping Billboard Top 100 Songs

To fetch the Billboard Top 100 songs for a specific date, we need to scrape the relevant information from the Billboard website. We can define a helper function called get_top_100_songs(date) to handle this task:

def get_top_100_songs(date):
    response = requests.get(f"https://www.billboard.com/charts/hot-100/{date}/")
    soup = BeautifulSoup(response.text, "html.parser")

    top_99 = [clean_text(song.getText()) for song in soup.find_all(
        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"
    )]
    number_one_song = [clean_text(song.getText()) for song in soup.find_all(
        class_="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"
    )]

    top_100 = number_one_song + top_99
    return top_100

The get_top_100_songs function performs the following steps:

  1. Sends a GET request to the Billboard website for the specified date.

  2. Parses the HTML response using BeautifulSoup.

  3. Extracts the song titles from the HTML using appropriate CSS selectors.

  4. Cleans the text by removing newlines and tabs.

  5. Returns a list of the top 100 songs.

Searching Tracks on Spotify

Next, we need to search for these songs on Spotify and retrieve their track IDs. We can define a function called search_tracks_in_spotify(spotify, top_100, year) to handle this task:

def search_tracks_in_spotify(spotify, top_100, year):
    track_ids = []
    access_token = get_spotify_access_token()

    for song in top_100:
        search_query = f"{song} year:{year}-{year + 1}"
        params = {
            'q': search_query,
            'type': 'track',
            'limit': 1,
        }

        headers = {
            "Authorization": f"Bearer {access_token}"
        }

        resp = requests.get("https://api.spotify.com/v1/search", params=params, headers=headers)
        search_results = resp.json()

        try:
            if 'tracks' in search_results and search_results['tracks']['items']:
                track = search_results['tracks']['items'][0]

                if song in track['name']:
                    song_id = track['id']
                    track_ids.append(song_id)
        except KeyError:
            print(f"No results found for '{song}' in {year}.")
        except IndexError:
            print(f"No results found for '{song}' in {year}.")

    return track_ids

The search_tracks_in_spotify function performs the following steps:

  1. Uses the get_spotify_access_token function to retrieve an access token for the Spotify API.

  2. Iterates through each song in the top 100 list.

  3. Constructs a search query for the song with an additional filter for the release year.

  4. Sends a GET request to the Spotify API search endpoint with the query and access token.

  5. Extracts the track ID from the search results and appends it to the track_ids list.

Creating a Playlist on Spotify

Once we have the track IDs, we can create a playlist on Spotify and add these tracks to it. We can define a function called create_playlist(spotify, username, playlist_name, track_ids) to handle this task:

def create_playlist(spotify, username, playlist_name, track_ids):
    global playlist
    if not check_if_playlist_exists(spotify, username, playlist_name):
        playlist = spotify.user_playlist_create(user=username, name=playlist_name, public=True)
        spotify.playlist_add_items(playlist_id=playlist['id'], items=track_ids)
        print(f"Playlist '{playlist_name}' created successfully")
        global playlist_created
        playlist_created = True
    else:
        print(f"Playlist '{playlist_name}' already exists.")

The create_playlist function performs the following steps:

  1. Checks if a playlist with the given name already exists for the user.

  2. If the playlist does not exist, it creates a new playlist using the user_playlist_create method.

  3. Adds the track IDs to the newly created playlist using the playlist_add_items method.

  4. Sets the playlist_created flag to True to indicate a successful playlist creation.

Web Application using Flask

Now that we have all the necessary functions, we can create a Flask web application to provide a user interface for the playlist creation process. The application will have a single route ("/") that serves an HTML template with a form to enter the date for the Billboard Top 100 songs.

The template, named "index.html," can be created in a folder called "templates" in the project directory. The template can use Jinja2 templating syntax to display messages and the playlist link after the form is submitted.

The Flask route handler function, index, handles both GET and POST requests. On a POST request, it retrieves the date from the form, fetches the top 100 songs from Billboard, searches for them on Spotify, and creates a playlist.

Finally, we run the Flask application using app.run():

@app.route("/", methods=["GET", "POST"])
def index():
    playlist_created = False
    playlist_link = None  # Declare the playlist_link variable

    if request.method == "POST":
        try:
            date = request.form.get("date")
            playlist_name = f"{date} Billboard Chart"
            year = int(date[:4])
        except ValueError:
            # Handle the case when an invalid date format is entered
            date = None
            playlist_name = None
            year = None

        top_100 = get_top_100_songs(date)

        scope = "playlist-modify-public"
        spotify = spotipy.Spotify(auth_manager=SpotifyOAuth(scope=scope))
        username = spotify.current_user()["id"]

        track_ids = search_tracks_in_spotify(spotify, top_100, year)

        create_playlist(spotify, username, playlist_name, track_ids)

        playlist_created = True
        playlist_link = playlist["external_urls"]["spotify"]

    return render_template("index.html", playlist_created=playlist_created, playlist_link=playlist_link)


if __name__ == "__main__":
    app.run(debug=False, host='0.0.0.0')

Conclusion

In this article, we have explored how to automatically create Spotify playlists for the Billboard Top 100 songs of a specific date. We have used Flask, BeautifulSoup, and Spotipy to fetch the song information from the Billboard website, search for the songs on Spotify, and create a playlist. This project demonstrates the power of web scraping and API integration in building useful applications for music enthusiasts.

The complete source code for this project can be found on GitHub.

Happy coding and enjoy listening to your favorite Billboard Top 100 songs!