while True:
Skip to content
Go back

Spotify の 「バイラルトップ 50 - 日本」 のプレイリストを作成するスクリプトを書いた

Published:  at  12:00 AM

つね日ごろから音楽の流行にはついていかなければいけないな、と心がけていて
個人的に流行の確度が高いと思っている Spotify の 「バイラルトップ 50 - 日本」 を
上位だけでも毎日かならず聴くようにしています。

Apple Music や Amazon Music でも日本で今よく聴かれている曲、
といったプレイリストがあるにはあるのですが、
同じアーティストの曲が上位にきたりしがちで、いまいちだと感じていました。

スクリプトを作った理由

  • 最近 USB-DAC を導入し、 PC でのハイレゾ再生ができるようになった
  • ただし Spotify は音質が Apple Music や Amazon Music Unlimited と比べると
    そこまでよろしくない (ロスレス, ハイレゾでのストリーミングがされていない)
  • なので、 SoundiizTune My Music といったサービスでプレイリストを同期して、
    Apple Music / Amazon Music Unlimited で聴きたい
  • ただし、 Spotify の公式チャートはプレイリスト形式ではなく、エクスポートできない

というものがありました。

そこで、 スクリプトを作成して、Soundiiz や Tune My Music といったサービスでも
読み込めるプレイリストに変換してしまうことにしました。

ひとまず名前は Spotify Japan Viral 50 Playlist Updater とでも名付けます。

今回は、 Python で Spotify Web API を利用するこのとのできる、
Spotipy というライブラリを使用しました。

Spotify はログインしてしまえば、こちらのチャートから CSV がダウンロードできるので、
その自動化には Playwright を使うことにします。

大まかな流れとしては以下のとおりです。

  • Playwright で Charts サイトにログインして CSV を取得
  • Spotipy + Refresh Token でプレイリストを操作
  • GitHub Actions + Docker で定期実行

セットアップ手順

とりあえずローカルでの実行手順を説明します。

ひとまずは Spotify プレイリストを操作するための Web アプリケーションが必要になるので、
Spotify for Developers にログインして、 Dashboard から Create app をします。

Spotify for Developers - Create app

App name, App Description は適当で OK で、今回はサーバーサイドのみで実行するため、
Redirect URIshttp://127.0.0.1:8888/callback とします。
127.0.0.1localhost と書きたいところですが、セキュリティ的によろしくないとされています。
Which API/SDKs are you planning to use? の項目は、
今回プレイリストを操作するだけなので、 Web API のみで大丈夫です。

そして、操作する公開プレイリストを Spotify で適当に作っておきます。

次に、 .env を作成します。

SPOTIPY_CLIENT_IDSPOTIPY_CLIENT_SECRETS
先ほどつくった Web アプリケーションのページから拾ってきてください。
SPOTIFY_PLAYLIST_ID はプレイリストの https://open.spotify.com/playlist/
につづいている文字列が ID になります。

SPOTIFY_REFRESH_TOKENSTATE_JSON_B64 は後ほどでてきます。

実行すると headless モードではない Chromium が立ち上がるので、ログインしてください。
もしかすると日本語が文字化けしているかもしれないですが、雰囲気でがんばってください。

ログインに成功すると、長い文字列 (Base64 エンコードされた JSON) が生成されるので、
それを全部、先ほど作った .env の STATE_JSON_B64 にコピペしてください。

save_session.py の中身はこちら

セッションは定期的に死んでしまうので、Refresh Token を使って、自動的に更新します。

DeprecationWarning が出ていて get_cached_token() を使うよう書いてありますが、
今回のように最初にリフレッシュトークンを取得するワンショットの用途においては適していません。
なので一旦は無視して大丈夫です。

URL に飛ぶと、 このサイトにアクセスできません とエラーになると思いますが、
127.0.0.1 にアクセスしているため、正常です。そのまま URL を全部コピペしてください。
トークンを取得できたら、 .envSPOTIFY_REFRESH_TOKEN に入力できます。

get_refresh_token.py の中身はこちら

ここまでできたら、あとは update_playlist.py を実行すればプレイリストが更新されます。

これで、プレイリストの中身が完全に空っぽにした後にチャートの曲が追加される処理が走ります。

update_playlist.py の中身はこちら

browser = p.chromium.launch(headless=True) の行を False にすると、
実際に Chromium が立ち上がって処理を眺めることができます。

User Agent や Geolocation の偽装をしているのは、開発中にうまく取得できなかったときの
トライアルアンドエラーの名残です。(なくてもおそらく動くとは思います。)

GitHub Actions と Docker を用いた定期実行

ここまで問題なくできているのであれば、あとは簡単です。

まず、 .env の内容を GitHub Secrets に登録します。
リポジトリの Settings > Secrets and variables > Actions に保存してください。

Dockerfile と Workflow ファイルのサンプルは以下になります。
多分そのままで動くと思います。

.github/workflows には以下のような Workflow ファイルを置いてください。

あとは GitHub に git push すれば定期的にスクリプトが実行されます。

今回は Viral 50 Japan のチャートを変換していますが、
Spotify Charts にあるものであれば同様に動くと思います。
その場合は update_playlist.py を適宜書き換えてみてください。

以下が今回作成できた、サンプルプレイリストです。

https://open.spotify.com/playlist/4Bf4jxM1WylLwqLmld8mbU

わたしが実際に Soundiiz でつかっているものなので、
今回の手順がめんどくさい方はそのまま使ってしまって大丈夫です。

参考にしていただければ幸いです。

PC でのハイレゾ再生環境については気が向いたらそのうち書こうと思います。



Previous Post
Astro + Sanity 構成にリニューアルした
Next Post
ITIL 4 ファンデーション合格した