PythonでSpotify API [情報の文字列検索]

Spotipy(Spotify APIのPython用ライブラリ)の[リファレンス](https://spotipy.readthedocs.io/en/latest/#module-spotipy.client)を見てると、アルバム取得、アーティスト取得、楽曲の取得等、いろんな情報をそれぞれ（アルバム情報なら`album()`とかで）取得できるようになっているのですが、どれも取得にはアルバムや楽曲ひとつひとつに紐づけられたIDとかURIが必要なのです。

たとえばアルバム情報取得(リファレンスより抜粋)なら、

> ```
> album(album_id)
>     returns a single album given the album’s ID, URIs or URL

> Parameters:
>     album_id - the album ID, URI or URL
> ```

特定のアルバムに紐付いたIDかURIを指定しないと、[アルバム情報編](https://qiita.com/EkatoPgm/items/8505a882e4c65ed7b715)で書いたような個別の情報は見れないわけですね。

# 文字列で検索（search()）

文字列から情報を検索するには、`search()`というモジュールを使います。

> ```
> search(q, limit=10, offset=0, type='track', market=None)
>     searches for an item

> Parameters:
>     * q - the search query
>     * limit - the number of items to return
>     * offset - the index of the first item to return
>     * type - the type of item to return.
>              One of ‘artist’, ‘album’, ‘track’ or ‘playlist’
>     * market - An ISO 3166-1 alpha-2 country code or the string from_token.

`market`でリリースされている、`q`に指定した文字列を含む`type`を、`offset`から数えて最大`limit`件取得するというもの。
（パラメータ名使って無理やり説明したので、ニュアンス違って伝わったらごめんなさい）

## まずは使ってみる

Gitにサンプルコードがあったので使ってみましょう。
以下は、サンプルコードに対して、クライアント認証の処理を追加したものです。

```python
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint

client_id = 'Client IDの値'
client_secret = 'Client Secretの値'
client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)
sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

result = sp.search(search_str)
pprint.pprint(result)
```

`search()`を上記のとおりに呼び出した場合、引数`q`に’Radiohead’が設定されます。指定しなかった引数を含めると、以下の指定で呼び出した場合と同様に動作します。

```python
search(q='Radiohead', limit=10, offset=0, type='track', market=None)
```

上記が、**'Radiohead'という文字列を含む楽曲(track)を最初の位置から10件検索する**という指定方法です。
デフォルト値として`limit`には10、`offset`には0、`type`には'track'が指定されるようです。

引数`type`には`artist`、`album`、`track`、`playlist`のどれかが指定できるので、`album`を指定したら、'Radiohead'という文字列を含むアルバムを検索するということになります。


ただこの、**「'Radiohead'という文字列を含む」**という表現ですが、
たとえば、`type`に`track`を指定した場合、
「'Radiohead'という文字列を**曲名**に含む」という意味ではありません。

もっかい書きますが

```python
search(q='Radiohead', limit=10, offset=0, type='track', market=None)
```

という指定の場合、
アーティスト名、曲名、アルバム名に、検索条件として'Radiohead'が適用されます。
つまり、'Radiohead'という曲名の曲が取得したいのに、'Radiohead'というアーティストの曲がズラーッと並んだりしてしまったりするわけ。

## もっと詳細に検索

じゃぁアーティスト検索とか曲名検索はできないのかと。できました。

たとえばこんな指定

```python
name = 'Radiohead'
search(q='track:'+name, limit=10, offset=0, type='track', market=None)
```

要するに'track:Radiohead'って検索。
この指定だと、曲名に'Radiohead'という文字列を含む曲が検索されます。
引数`type`と同様、`album`、`track`、`playlist`が指定できるようです。

## (例)楽曲の解析情報の取得

たとえばこれまでに説明したとおり、`search()`による検索で取得した楽曲情報は[リファレンス](https://developer.spotify.com/documentation/web-api/reference/tracks/get-track/)によると、名前やURIなどの基本データを格納したものになります。

Spotify APIでは楽曲ごとの解析データも取得でき、要するに、ある曲のある地点はどのくらいのテンポなのかとか、どんくらい盛り上がる曲なんだってのがデータ化されているみたいです。（参照：[Get Audio Analysis for a Track](https://developer.spotify.com/documentation/web-api/reference/tracks/get-audio-analysis/)、[Get Audio Features for a Track](https://developer.spotify.com/documentation/web-api/reference/tracks/get-audio-features/)）

`search()`で取得した情報を使って、これらの応用情報を取得してみます！
上で説明した例に、処理を追加します。

```python
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
import sys
import pprint

if len(sys.argv) > 1:
		search_str = sys.argv[1]
else:
		search_str = 'Radiohead'

client_id = 'Client IDの値'
client_secret = 'Client Secretの値'
client_credentials_manager = spotipy.oauth2.SpotifyClientCredentials(client_id, client_secret)

sp = spotipy.Spotify(client_credentials_manager=client_credentials_manager)

result = sp.search(q='track:Radiohead', limit=10, offset=0, type='track', market=None) #sp.search(search_str)

id_list = []
for track in result['tracks']['items']:
		id = track['id']
		id_list.append(id)

features = sp.audio_features(id_list)
pprint.pprint(features)
```

`search()`で取得した情報から楽曲ごとの`id`を抜き出し、
リストに格納した上で`audio_features()`を呼び出します。

以下のように、楽曲の解析情報がとれます。
（リストなので2曲目以降は省略しますね）

```yaml
[{'acousticness': 0.721,
  'analysis_url': 'https://api.spotify.com/v1/audio-analysis/1VIzH2prXPpvQO8KspM3GU',
  'danceability': 0.806,
  'duration_ms': 168387,
  'energy': 0.0842,
  'id': '1VIzH2prXPpvQO8KspM3GU',
  'instrumentalness': 0.401,
  'key': 0,
  'liveness': 0.0789,
  'loudness': -16.303,
  'mode': 1,
  'speechiness': 0.0629,
  'tempo': 95.979,
  'time_signature': 4,
  'track_href': 'https://api.spotify.com/v1/tracks/1VIzH2prXPpvQO8KspM3GU',
  'type': 'audio_features',
  'uri': 'spotify:track:1VIzH2prXPpvQO8KspM3GU',
  'valence': 0.446},
  ...
]
```

キーやテンポなどが入った解析情報を取得することができました！
`danceability`や`liveness`など、面白そうなデータがたくさん...

これらの情報を使ってどんなことができるか、楽しみになってきました。
今回はここまで！