Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
25
Help us understand the problem. What are the problem?
@Prgckwb

PythonのSpotify APIで指定したアーティストの人気曲を取得する

まえがき

音楽ストリーミングアプリSpotifyから提供されているSpotify API for Pythonの Spotipyを使って、ユーザの指定したアーティストの人気楽曲をSpotifyから取得するというものです。

前提条件

事前に必要なものは、Spotify for Developersへの登録と、そのサイト内での新規アプリ作成です。また、Pythonの環境構築は済んでいるものとします。

手順

はじめに、Spotify for DevelopersのDASHBOARDからClient IDClient Secretを取得し、メモしておきます。セキュリティ的に問題があるのでこの文字列は第三者に見破られないようにしてください。
Spotify for Developersの画面
上の画像で赤線で隠してある部分がClient IDで青のそれがClient Secretです。

この2つのトークンから、以下のコードのようにしてAPIへのアクセス権を得ます。

sample_spotipy.py(一部)
import spotipy

client_id = '自分のClient ID'
client_secret = '自分のClient Secret'

client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)
spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

さて、今回書くコードは(ユーザが指定した歌手名)からその歌手の人気曲を得るものです。
SpotipyのWEB APIリファレンスによると、内部ではアーティストのidを指定することでtop-tracksというものを取得することができます。

top-tracksの仕様
{
  "tracks": [ {
    "album" : {
      "album_type" : "album",
      "artists" : [ {
        "external_urls" : {
          "spotify" : "https://open.spotify.com/artist/43ZHCT0cAZBISjO8DG9PnE"
        },
        "href" : "https://api.spotify.com/v1/artists/43ZHCT0cAZBISjO8DG9PnE",
        "id" : "43ZHCT0cAZBISjO8DG9PnE",
        "name" : "Elvis Presley",
        "type" : "artist",
        "uri" : "spotify:artist:43ZHCT0cAZBISjO8DG9PnE"
      } ],
      "available_markets" : [ "AD", "AR", "AT", "AU", "BE", "BG", "BO", "BR", "CA", "CH", "CL", "CO", "CR", "CY", "CZ", "DE", "DK", "DO", "EC", "EE", "ES", "FI", "FR", "GB", "GR", "GT", "HK", "HN", "HU", "ID", "IE", "IS", "IT", "JP", "LI", "LT", "LU", "LV", "MC", "MT", "MX", "MY", "NI", "NL", "NO", "NZ", "PA", "PE", "PH", "PL", "PT", "PY", "SE", "SG", "SK", "SV", "TR", "TW", "US", "UY" ],
      "external_urls" : {
        "spotify" : "https://open.spotify.com/album/7xe8VI48TxUpU1IIo0RfGi"
      },
      "href" : "https://api.spotify.com/v1/albums/7xe8VI48TxUpU1IIo0RfGi",
      "id" : "7xe8VI48TxUpU1IIo0RfGi",
      "images" : [ {
        "height" : 640,
        "url" : "https://i.scdn.co/image/4295b5ff74d4f944367144acbe616b6f62d20b17",
        "width" : 640
      }, {
        "height" : 300,
        "url" : "https://i.scdn.co/image/203104e5843248c700b078f391d4bc759c5d7f47",
        "width" : 300
      }, {
        "height" : 64,
        "url" : "https://i.scdn.co/image/0c0a172373b0211c590b241270d05b70889075a1",
        "width" : 64
      } ],
      "name" : "Blue Hawaii",
      "type" : "album",
      "uri" : "spotify:album:7xe8VI48TxUpU1IIo0RfGi"
    },
    "artists" : [ {
      "external_urls" : {
        "spotify" : "https://open.spotify.com/artist/43ZHCT0cAZBISjO8DG9PnE"
      },
      "href" : "https://api.spotify.com/v1/artists/43ZHCT0cAZBISjO8DG9PnE",
      "id" : "43ZHCT0cAZBISjO8DG9PnE",
      "name" : "Elvis Presley",
      "type" : "artist",
      "uri" : "spotify:artist:43ZHCT0cAZBISjO8DG9PnE"
    } ],
    "available_markets" : [ "AD", "AR", "AT", "AU", "BE", "BG", "BO", "BR", "CA", "CH", "CL", "CO", "CR", "CY", "CZ", "DE", "DK", "DO", "EC", "EE", "ES", "FI", "FR", "GB", "GR", "GT", "HK", "HN", "HU", "ID", "IE", "IS", "IT", "JP", "LI", "LT", "LU", "LV", "MC", "MT", "MX", "MY", "NI", "NL", "NO", "NZ", "PA", "PE", "PH", "PL", "PT", "PY", "SE", "SG", "SK", "SV", "TR", "TW", "US", "UY" ],
    "disc_number" : 1,
    "duration_ms" : 179773,
    "explicit" : false,
    "external_ids" : {
      "isrc" : "USRC16101350"
    },
    "external_urls" : {
      "spotify" : "https://open.spotify.com/track/44AyOl4qVkzS48vBsbNXaC"
    },
    "href" : "https://api.spotify.com/v1/tracks/44AyOl4qVkzS48vBsbNXaC",
    "id" : "44AyOl4qVkzS48vBsbNXaC",
    "name" : "Can't Help Falling in Love",
    "popularity" : 70,
    "preview_url" : "https://p.scdn.co/mp3-preview/26e409b39a2da6dc18fab61020c90be2938dc0e9",
    "track_number" : 5,
    "type" : "track",
    "uri" : "spotify:track:44AyOl4qVkzS48vBsbNXaC"
  }, {
...
  } ]
}

まずは指定した文字列で表される歌手のSpotify内でのIDを返す関数を作ってみます。
さきほどのWEB APIリファレンスからspotify.searchによって得られるオブジェクトは

search
{
    "artists": {
        "href": "https://api.spotify.com/v1/search?query=tania+bowra&offset=0&limit=20&type=artist",
        "items": [
            {
                "external_urls": {
                    "spotify": "https://open.spotify.com/artist/08td7MxkoHQkXnWAYD8d6Q"
                },
                "genres": [],
                "href": "https://api.spotify.com/v1/artists/08td7MxkoHQkXnWAYD8d6Q",
                "id": "08td7MxkoHQkXnWAYD8d6Q",
                "images": [
                    {
                        "height": 640,
                        "url": "https://i.scdn.co/image/f2798ddab0c7b76dc2d270b65c4f67ddef7f6718",
                        "width": 640
                    },
                    {
                        "height": 300,
                        "url": "https://i.scdn.co/image/b414091165ea0f4172089c2fc67bb35aa37cfc55",
                        "width": 300
                    },
                    {
                        "height": 64,
                        "url": "https://i.scdn.co/image/8522fc78be4bf4e83fea8e67bb742e7d3dfe21b4",
                        "width": 64
                    }
                ],
                "name": "Tania Bowra",
                "popularity": 0,
                "type": "artist",
                "uri": "spotify:artist:08td7MxkoHQkXnWAYD8d6Q"
            }
        ],
        "limit": 20,
        "next": null,
        "offset": 0,
        "previous": null,
        "total": 1
    }
}

のようになっているので、(searchで返された結果)→artists→items→の0番目要素→idで辿っていくのが良さそうです。

注意 itemsの0番目要素だからと言って必ず想定したアーティストが返されるとは限らず、さらにはIndexErrorを発生する場合があります。

sample_spotipy.py(一部)
def getIdByArtist(artist_name):
    results = spotify.search(q="artist:" + artist_name, type="artist")
    items = results["artists"]["items"]
    artist = items[0]
    artist_id = artist["id"]
    return artist_id

次に得られたIDからtop-tracksの情報を取得します。Spotipyではspotify.artist_top_tracks()関数の引数として調べたいアーティストのIDを渡すことで最大10個のtrackオブジェクトが返されます。

sample_spotipy.py(一部)
def getTopSongs(artist_name):
    num = 10  # 調べたい楽曲数(最大10)
    try:
        search_id = getIdByArtist(artist_name)
        artist_top_tracks = spotify.artist_top_tracks(search_id, country="JP")["tracks"]

        print(artist_name + f" Top{num} Songs")

        for i in range(num):
            print(str(i + 1) + ". " + artist_top_tracks[i]["name"])

    except IndexError:
        print("IndexError has occurred!")
    except AttributeError:
        print("AttributeError has occurred!")

IndexErrorやAttributeErrorは正しく検索が行えなかったときに起こることがあります。
ここまででコードが書けたので、試しにMr.Children、ヨルシカ、oasisの人気曲ベスト10を出力するテストコードを書いてみます。

sample_spotipy.py(一部)
if __name__ == '__main__':
    getTopSongs("Mr.Children")
    print()
    getTopSongs("ヨルシカ")
    print()
    getTopSongs("oasis")

実行してみると以下のような出力が得られます。(2021/7/18現在)

出力
Mr.Children Top10 Songs
1. HANABI
2. Tomorrow never knows
3. innocent world
4. 足音 ~Be Strong
5. 名もなき詩
6. Sign
7. シーソーゲーム~勇敢な恋の歌~
8. しるし
9. Brand new planet
10. 抱きしめたい

ヨルシカ Top10 Songs
1. ただ君に晴れ
2. 春泥棒
3. 又三郎
4. だから僕は音楽を辞めた
5. 花に亡霊
6. 言って。
7. ヒッチコック
8. 風を食む
9. 嘘月
10. 藍二乗

oasis Top10 Songs
1. Wonderwall
2. Don't Look Back in Anger
3. Champagne Supernova
4. Stop Crying Your Heart Out
5. Live Forever
6. Supersonic
7. Stand by Me
8. Half the World Away
9. Whatever
10. She's Electric

無事にTop-Tracksが出力できました。

以下、サンプルコード全文です。

sample_spotipy.py
import spotipy

client_id = '自分のClient ID'
client_secret = '自分のClient Secret'

client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)
spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

def getIdByArtist(artist_name):
    results = spotify.search(q="artist:" + artist_name, type="artist")
    items = results["artists"]["items"]
    artist = items[0]
    artist_id = artist["id"]
    return artist_id


def getTopSongs(artist_name):
    num = 10  # 調べたい楽曲数(最大10)
    try:
        search_id = getIdByArtist(artist_name)
        artist_top_tracks = spotify.artist_top_tracks(search_id, country="JP")["tracks"]

        print(artist_name + f" Top{num} Songs")

        for i in range(num):
            print(str(i + 1) + ". " + artist_top_tracks[i]["name"])

    except IndexError:
        print("IndexError has occurred!")
    except AttributeError:
        print("AttributeError has occurred!")


if __name__ == '__main__':
    getTopSongs("Mr.Children")
    print()
    getTopSongs("ヨルシカ")
    print()
    getTopSongs("oasis")

問題点

指定したアーティストからSpotifyのアーティストIDの取得をかなり簡単にしているので、一字一句間違えずに指定しているのに思ったアーティストとは違うものがヒットする場合や、日本語ではなく英語やローマ字表記にしないと見つからない問題があります。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
25
Help us understand the problem. What are the problem?