uniface.hub

uniface.hub

ユニフェイスの開発者ブログ


Title Spotify Apiを使ってみた
  • 2021年4月9日
  • hozumi
Spotify Apiを使ってみた

初めまして、齢26でぎっくり腰の穂積です。

突然ですが私は、洋楽も邦楽も関係なく音楽を聴くのが好きです。

そして海外のチャートTOP100を聴いていると
海外ってhip hopばっか聴いてるな、逆に日本はpopばっか聴いてるなってイメージでした。

そこで、Spotifyのapiを使ってヒットチャートを分析し、実際どのジャンルが今聴かれているのか調べてみようと思います。

Spotifyが用意してくれている、pythonの「spotipy」というライブラリを使ってデータの取得、分析を行います。

準備

初めに、「spotipy」をインストールします。

pip install spotipy

次に、「spotipy」を利用するために、アカウントを作ってclient_idとclient_secretを取得する必要があります。

Spotify for Developersでアカウントを作ってDASHBOARDを開き、アプリを作成。
そこでclient_idとclient_secretを取得します。

最後に、Spotify ChartsのDownlode CSVを押下してランキングデータのCSVをダウンロードしておきます。(今回は、GLOBAL WEEKLY 04/01/2021 のデータをダウンロードしました。)

いざ実装

先ほど取得した、client_idとclient_secretを設定し、
spotify.search()を使ってアーティストのジャンルを取得します。

client_id = 'client_id'
client_secret = 'client_secret'
# OAuth 2.0 クライアント認証
client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)
spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

動かしてみる

楽曲にジャンルが紐づいているわけではなさそうだったので
アーティストに紐づくジャンルを全て取得して数を数えてみました。

def get_genre():
    genreList = []
    # ダウンロードしたcsvを1行ずつ読む。
    with open('regional-global-weekly-latest.csv',encoding="utf_8") as f:
        reader = csv.reader(f)
        for row in reader:
            if reader.line_num == 1 or reader.line_num == 2:
                print('notCount')
            else:
                name = row[2]
                # アーティスト情報を取得
                result = spotify.search(q='artist:' + name, type='artist')
                artists = result['artists']['items']

                if not len(artists) == 0:
                    for g in artists[0]['genres']:
                        genreList.append(g)

    genre_count = {}

    for genre in list(set(genreList)):
        genre_count[genre] = genreList.count(genre)

    result = sorted(genre_count.items(),  key=lambda x:x[1] , reverse=True)

結果

ジャンル
pop47
post-teen pop26
dance pop17
pop rap14
canadian pop14
trap latino13
rap11
reggaeton11
latin9
reggaeton colombiano6

んージャンルが想像していたよりもだいぶ細かかったです…汗

ランキングTOP100のアーティストから、73ものジャンルが取得できました。

そして堂々の1位がpopという、私の想定外の結果になりました。

しかし、〇〇rapもtrapもhip hopだろうということで、ジャンルを変換してみます。

下記のような感じで、rapとつくものはhip hopに、popとつくものはpopにします。
今回 pop rapはhip hopとします(独断と偏見)

def convert_category(genre):
    if 'hip hop' in genre or 'rap' in genre:
        genre = 'hip hop'
    elif 'pop' in genre:
        genre = 'pop'
    elif 'rock' in genre:
        genre = 'rock'

    return genre
def get_genre():
    genreList = []
    with open('regional-global-weekly-latest.csv',encoding="utf_8") as f:
        reader = csv.reader(f)
        for row in reader:
            if reader.line_num == 1 or reader.line_num == 2:
                print('notCount')
            else:
                name = row[2]
                result = spotify.search(q='artist:' + name, type='artist')
                artists = result['artists']['items']

                if not len(artists) == 0:
                    for g in artists[0]['genres']:
                        genreList.append(convert_category(g))

    genre_count = {}

    for genre in list(set(genreList)):
        genre_count[genre] = genreList.count(genre)

    result = sorted(genre_count.items(),  key=lambda x:x[1] , reverse=True)

結果2

ジャンル
pop138
hip hop69
reggaeton11
latin9
reggaeton colombiano6
rock6
tropical house5
slap house5
house4
edm4

pop強い

houseも結構聴かれていますね。

1アーティストに対してpop/teen pop/country pop
みたいにジャンルが重複していることがあるので

今度は1アーティストから1ジャンル取得して、結果をみてみようと思います。

def get_genre():
    genreList = []
    with open('regional-global-weekly-latest.csv',encoding="utf_8") as f:
        reader = csv.reader(f)
        for row in reader:
            if reader.line_num == 1 or reader.line_num == 2:
                print('notCount')
            else:
                name = row[2]
                result = spotify.search(q='artist:' + name, type='artist')
                artists = result['artists']['items']

                if not len(artists) == 0:
                    genres = artists[0]['genres']
                    if genres:
                        # genre[]に複数のジャンルが入っているので、一番目のジャンルを取得
                        genreList.append(convert_category(genres[0]))

    genre_count = {}

    for genre in list(set(genreList)):
        genre_count[genre] = genreList.count(genre)

    result = sorted(genre_count.items(),  key=lambda x:x[1] , reverse=True)

結果3

ジャンル
pop48
hip hop19
latin8
brooklyn drill4
rock3
alt z3
canadian contemporary r&b2
reggaeton2
slap house1
sertanejo1

popのが今週のチャート的には聴かれていそうですね…

全然体感と違いました、ジャスティンビーバーが新譜を出したからかな。

日本のチャートも調べてみた

ジャンル
pop59
rock18
anime8
acoustic6
latin2
glam metal1
vocaloid1
hip hop1

日本も最近hip hop聴く人増えたよなぁって印象でしたが
チャート的にはそうでもないみたいでした。

日本はまだhip hopよりrockを聴く人が多いようです。

終わりに

今回はSpotifyのapiを使ってアーティストからジャンルを取得し
聴かれているジャンルを調べてみました。

Spotifyのapiは、情報を見る以外にも、音楽の再生とかプレイリスト作るとか
できることはまだまだありそうだったので、また触ってみようと思います。

追記

同アーティストの何曲がTOP100入りしてるか見てみました。
Justin Biberやはり強いですね。

アーティスジャンル
Justin Bieber9‘canadian pop’, ‘pop’, ‘post-teen pop’
Dua Lipa3‘dance pop’, ‘pop’, ‘uk pop’
KAROL G3‘latin’, ‘reggaeton’, ‘reggaeton colombiano’, ‘trap latino’
Harry Styles3‘pop’, ‘post-teen pop’
Travis Scott2‘rap’, ‘slap house’
Pop Smoke2‘brooklyn drill’
Drake2‘canadian hip hop’, ‘canadian pop’, ‘hip hop’, ‘pop rap’, ‘rap’, ‘toronto rap’
Imagine Dragons2‘modern rock’, ‘rock’
Cardi B2‘pop’, ‘pop rap’, ‘post-teen pop’, ‘rap’
Post Malone2‘dfw rap’, ‘melodic rap’, ‘rap’
Ariana Grande2‘pop’, ‘post-teen pop’
Lewis Capaldi2‘pop’, ‘uk pop’
Joel Corry2‘dance pop’, ‘edm’, ‘house’, ‘pop dance’, ‘tropical house’, ‘uk dance’
Billie Eilish2‘electropop’, ‘pop’
Lil Tjay2‘brooklyn drill’, ‘melodic rap’, ‘nyc rap’
Maroon 52‘pop’, ‘pop rock’
The Weeknd 2‘canadian contemporary r&b’, ‘canadian pop’, ‘pop’
Bad Bunny2‘latin’, ‘reggaeton’, ‘trap latino’
Lil Nas X2‘country rap’, ‘lgbtq+ hip hop’, ‘pop rap’, ‘queer country’

このランキング見ていると、pop smokeがbrooklyn drillというジャンルですけど、彼はラッパーなのでhio hopにカウントしても良かったかなとか、Cardi Bがpopに分類されてたり、ジャンルの抽出の仕方に反省点があったな、と思いました。

最近の音楽ってR&Bとhip hopの融合とか、popやsoulの中でrapやってたりと多様化してきているので

一概にこれがhip hopだ!とかpopだ!とか言えないですね。