Skip to content

Commit

Permalink
v1
Browse files Browse the repository at this point in the history
  • Loading branch information
Markkop committed May 11, 2023
1 parent 6972310 commit e2e8f34
Show file tree
Hide file tree
Showing 6 changed files with 414 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
SPOTIFY_CLIENT_ID=
SPOTIFY_CLIENT_SECRET=
SPOTIFY_REDIRECT_URI=
SPOTIFY_ACCESS_TOKEN=
SPOTIFY_PLAYLIST_ID=
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
node_modules
node_modules
.env
170 changes: 170 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# 🎧 Discover Your Noise

This is a simple Node.js script that counts the genres of songs in a Spotify playlist. The script uses the Spotify Web API to get the playlist's artists, and then it uses Puppeteer to scrape the genres of each artist from everynoise.com.

## Prerequisites

Before you begin, ensure you have met the following requirements:

- You have installed Node.js and npm.
- You have a Spotify account.

## Installation

To install Genre-Scrapper, follow these steps:

```bash
git clone git@github.com:Markkop/discover-your-noise.git
cd genre-scrapper
npm install # or yarn install
```

## Obtaining Spotify API Keys

In order to use this script, you will need a Spotify Client ID, Client Secret, and an access token. Here's how you get them:

1. Go to the [Spotify Developer Dashboard](https://developer.spotify.com/dashboard/login).
2. Log in to your Spotify account.
3. Click on 'Create an App', fill out the form, and click 'Create'.
4. Now you are in your application's dashboard, you can see your Client ID and Client Secret. Copy them somewhere safe.
5. To get an access token, make this POST request: https://developer.spotify.com/documentation/web-api/tutorials/getting-started#request-an-access-token

**Note:** Access tokens expire after a certain period of time, so you may need to refresh it if your script stops working.

## Obtaining Spotify Playlist ID

1. Open the Spotify app (desktop or web version) and navigate to the desired playlist.
2. Click on the three-dot menu next to the "PLAY" button.
3. Select "Share" from the drop-down menu, then click on "Copy Playlist Link". This will copy a URL to your clipboard.
4. The URL you copied should look something like this: `https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M?si=12345abc6789`. The Playlist ID is the alphanumeric string after `/playlist/` and before the `?`. In this case, `37i9dQZF1DXcBWIGoYBM5M` is the Playlist ID.

## Setting Up Environment Variables

Copy `.env.example`, rename it to `.env` and insert your keys and tokens like this:

```
SPOTIFY_CLIENT_ID=your-spotify-client-id
SPOTIFY_CLIENT_SECRET=your-spotify-client-secret
SPOTIFY_REDIRECT_URI=your-app-redirect-uri
SPOTIFY_ACCESS_TOKEN=your-spotify-access-token
SPOTIFY_PLAYLIST_ID=your-spotify-playlist-id
```

## Running the Script

To run Genre-Scrapper, use this command:

```bash
npm start # or yarn start
```

This will start the script, and it will print the count of genres in the specified Spotify playlist to the console.

Eg. for playlist:
https://open.spotify.com/playlist/2i2vaDkkinuropvyOSCm2B

```js
[
[ 'indietronica', 7 ],
[ 'brazilian indie', 7 ],
[ 'nova mpb', 6 ],
[ 'rock', 6 ],
[ 'indie rock', 5 ],
[ 'art pop', 4 ],
[ 'latin alternative', 4 ],
[ 'modern rock', 4 ],
[ 'nova musica carioca', 3 ],
[ 'neo-psychedelic', 3 ],
[ 'neo-psicodelia brasileira', 3 ],
[ 'downtempo', 3 ],
[ 'classic rock', 3 ],
[ 'permanent wave', 3 ],
[ 'chamber pop', 3 ],
[ 'metropopolis', 2 ],
[ 'indie soul', 2 ],
[ 'tropicalia', 2 ],
[ 'mpb', 2 ],
[ 'psicodelia brasileira', 2 ],
[ 'bossa nova', 2 ],
[ 'samba', 2 ],
[ 'synthwave', 2 ],
[ 'world', 2 ],
[ 'french psychedelic', 2 ],
[ 'acid rock', 2 ],
[ 'psychedelic rock', 2 ],
[ 'hard rock', 2 ],
[ 'album rock', 2 ],
[ 'pop lgbtq+ brasileira', 2 ],
[ 'pov: indie', 2 ],
[ 'pop', 2 ],
[ 'latin afrobeat', 2 ],
[ 'garage rock', 2 ],
[ 'chicha', 2 ],
[ 'argentine indie', 2 ],
[ 'manguebeat', 2 ],
[ 'dream pop', 2 ],
[ 'deep downtempo fusion', 1 ],
[ 'downtempo fusion', 1 ],
[ 'pop nacional', 1 ],
[ 'psychedelic pop', 1 ],
[ 'portland hip hop', 1 ],
[ 'kiwi rock', 1 ],
[ 'nu jazz', 1 ],
[ 'balkan beats', 1 ],
[ 'electro swing', 1 ],
[ 'samba-rock', 1 ],
[ 'french indie pop', 1 ],
[ 'french indietronica', 1 ],
[ 'french rock', 1 ],
[ 'uk alternative pop', 1 ],
[ 'proto-metal', 1 ],
[ 'folk rock', 1 ],
[ 'blues rock', 1 ],
[ 'singer-songwriter', 1 ],
[ 'mellow gold', 1 ],
[ 'tecnobrega', 1 ],
[ 'musica popular paraense', 1 ],
[ 'vaporwave', 1 ],
[ 'future funk', 1 ],
[ 'chillsynth', 1 ],
[ 'hardvapour', 1 ],
[ 'hypnagogic pop', 1 ],
[ 'mallsoft', 1 ],
[ 'slushwave', 1 ],
[ 'trap beats', 1 ],
[ 'canadian electropop', 1 ],
[ 'neo-synthpop', 1 ],
[ 'grave wave', 1 ],
[ 'rock paraibano', 1 ],
[ 'musica campista', 1 ],
[ 'musica paraibana', 1 ],
[ 'psychedelic soul', 1 ],
[ 'funk rock', 1 ],
[ 'funk', 1 ],
[ 'p funk', 1 ],
[ 'soul', 1 ],
[ 'art rock', 1 ],
[ 'glam rock', 1 ],
[ 'electronica', 1 ],
[ 'bedroom pop', 1 ],
[ 'indie pop', 1 ],
[ 'shimmer psych', 1 ],
[ 'chillwave', 1 ],
[ 'vapor twitch', 1 ],
[ 'wonky', 1 ],
[ 'brooklyn indie', 1 ],
[ 'umbanda', 1 ],
[ 'brazilian rock', 1 ],
[ 'brazilian reggae', 1 ],
[ 'afrobeat brasileiro', 1 ],
[ 'brass band brasileiro', 1 ],
[ 'afrofuturismo brasileiro', 1 ],
[ 'instrumental funk', 1 ],
[ 'brazilian indie rock', 1 ],
[ 'sheffield indie', 1 ],
[ 'baroque pop', 1 ],
[ 'quebec indie', 1 ],
[ 'canadian indie', 1 ],
... 49 more items
]
```
61 changes: 61 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
const puppeteer = require("puppeteer");
const SpotifyWebApi = require("spotify-web-api-node");
const dotenv = require("dotenv");
dotenv.config();

const spotifyApi = new SpotifyWebApi({
clientId: process.env.SPOTIFY_CLIENT_ID,
clientSecret: process.env.SPOTIFY_CLIENT_SECRET,
redirectUri: process.env.SPOTIFY_REDIRECT_URI,
accessToken: process.env.SPOTIFY_ACCESS_TOKEN,
});
const getGenres = async (browser, artist) => {
const page = await browser.newPage();
const url =
"https://everynoise.com/lookup.cgi?who=" + encodeURIComponent(artist);
await page.goto(url);
const genres = await page.evaluate(() => {
const anchorTags = document.querySelectorAll("div>a:not([title])");
return Array.from(anchorTags).map((a) => a.textContent);
});
await page.close();
return genres;
};

const getPlaylistArtists = async (playlistId) => {
const data = await spotifyApi.getPlaylist(playlistId);
const tracks = data.body.tracks.items;
const artists = tracks.map((track) => track.track.artists[0].name);
return [...new Set(artists)];
};

const countGenres = async (playlistId) => {
const artists = await getPlaylistArtists(playlistId);
const browser = await puppeteer.launch();

let genresCount = {};
for (const artist of artists) {
const genres = await getGenres(browser, artist);
console.log(`Genres for ${artist}: ${genres}`);

for (const genre of genres) {
if (genre in genresCount) {
genresCount[genre]++;
} else {
genresCount[genre] = 1;
}
}
}
await browser.close();

const sortedGenresCount = Object.entries(genresCount).sort(
(a, b) => b[1] - a[1]
);

console.log(sortedGenresCount);
return sortedGenresCount;
};

countGenres(process.env.SPOTIFY_PLAYLIST_ID)
.then(console.log)
.catch(console.error);
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"puppeteer": "^20.1.2"
"dotenv": "^16.0.3",
"puppeteer": "^20.1.2",
"spotify-web-api-node": "^5.0.2"
}
}
Loading

0 comments on commit e2e8f34

Please sign in to comment.