在Spotify API中搜索播客剧集时获取最新结果

huangapple go评论93阅读模式
英文:

Getting Most Recent Results when Searching for Podcast Episodes in the Spotify API

问题

我假装获取最新的剧集,当它们的标题或描述包含一些文本时,比如,“tim ferriss”。这是否可能?我成功使用搜索项目选项来搜索特定的字符串,但我无法弄清楚如何按发布日期排序结果。提前感谢。

英文:

I pretend to get the most recent episodes for when their title or description contain some text like, for example, "tim ferriss". Is this possible? I managed to search for certain strings with Search for Item option but I can't figure out how to sort the results by publication datetime. Thanks in advance.

答案1

得分: 0

Search for Item API没有排序选项。

因此,您必须根据自己的逻辑在客户端进行排序。

您没有指定语言选项。
我用node.js制作了一个演示代码。

演示代码

const express = require("express")
const axios = require('axios')
const cors = require("cors")
const fs = require('fs')

const app = express()
app.use(cors())

// 凭据
CLIENT_ID = "<your Client ID>"
CLIENT_SECRET = "<your Client Secret>"
PORT = 3000 // it is located in Spotify dashboard's Redirect URIs, my port is 3000, should be replace your Port
REDIRECT_URI = `http://localhost:${PORT}/callback` // my case is 'http://localhost:3000/callback'
SCOPE = [
    'user-read-private'
]

// 获取访问令牌
const getToken = async (code) => {
    try {
        const resp = await axios.post(
            url = 'https://accounts.spotify.com/api/token',
            data = new URLSearchParams({
                'grant_type': 'authorization_code',
                'redirect_uri': REDIRECT_URI,
                'code': code
            }),
            config = {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                auth: {
                    username: CLIENT_ID,
                    password: CLIENT_SECRET
                }
            })
        return Promise.resolve(resp.data.access_token);
    } catch (err) {
        console.error(err)
        return Promise.reject(err)
    }
}

// 通过查询获取剧集
const getEpisodes = async (token, query) => {
    try {
        let offset = 0
        let next = 1
        const limit = 50;
        const episodes = [];

        const encodeString = encodeURI(query)
        while (next != null) {
            const resp = await axios.get(
                url = `https://api.spotify.com/v1/search?q=${encodeString}&type=episode&limit=${limit}&offset=${offset}`,
                config = {
                    headers: {
                        'Content-Type': 'application/json',
                        'Authorization': `Bearer ${token}`,
                    }
                })
            for(const item of resp.data.episodes.items) {
                if(item?.name != null) {
                    episodes.push({
                        name: item.name,
                        release_date: item.release_date,
                        external_urls: item.external_urls.spotify,
                        duration_ms: item.duration_ms,
                        type: item.type,
                        id : item.id,
                        // <extension data>
                        // audio_preview_url: item.audio_preview_url,
                        // description: item.description,
                        // html_description: item.html_description,
                        // images : item.images,
                    })
                }
            }
            offset = offset + limit
            next = resp.data.episodes.next
        }
        // 在发布日期排序后
        return Promise.resolve(episodes.sort((a,b) => Date.parse(b.release_date) - Date.parse(a.release_date)));
    } catch (err) {
        console.error(err)
        return Promise.reject(err)
    }
}

// 登录URL
app.get("/login", (request, response) => {
    const redirect_url = `https://accounts.spotify.com/authorize?response_type=code&client_id=${CLIENT_ID}&scope=${SCOPE}&state=123456&redirect_uri=${REDIRECT_URI}&prompt=consent`
    response.redirect(redirect_url);
})

// 回调URL
app.get("/callback", async (request, response) => {
    const code = request.query["code"]
    getToken(code)
        .then(access_token => {
            getEpisodes(access_token,"tim ferriss")
                .then(episodes => {
                    // For file save
                    const data = JSON.stringify(episodes);
                    fs.writeFileSync('simple_results.json', data);

                    // For browser displaying 
                    return response.send({
                        'Total episodes length: ': episodes.length,
                        'Episodes': episodes
                    });
                })

        })
        .catch(error => {
            console.log(error.message);
        })
})


// 启动express服务器
app.listen(PORT, () => {
    console.log(`Listening on :${PORT}`)
})

安装依赖项

npm install axios express cors fs

运行服务器

node demo.js

登录并获取剧集

端口号应与您的端口号匹配。

http://localhost:3000/user

结果

在Spotify API中搜索播客剧集时获取最新结果

如果要查看完整数据,请取消注释getEpisodes()中的代码

episodes.push({
    name: item.name,
    release_date: item.release_date,
    external_urls: item.external_urls.spotify,
    duration_ms: item.duration_ms,
    type: item.type,
    id : item.id,
    // <extension data>
    audio_preview_url: item.audio_preview_url,
    description: item.description,
    html_description: item.html_description,
    images : item.images,
})

更新 - 添加Python演示

另存为get-episodes.py文件名。

import spotipy
from spotipy.oauth2 import SpotifyOAuth
import pandas as pd
from urllib.parse import quote
import numpy as np
import datetime as DT

# 将您的Spotify API凭据设置为环境变量,它将被spotipy API自动选择
CLIENT_ID = "9d53d43408c04c089e58f6b615f44bf9"
CLIENT_SECRET = "96f14dc115644d83b8957b77fcface31"
PORT = 3000
REDIRECT_URI = "http://localhost:{0}/callback".format(PORT)

# 只需此范围即可获取user_recently_played API
scope = "user-read-recently-played"

# 此API调用会引发Web浏览器,并要求用户使用Authorization Code流进行登录以获取回调
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(
    client_id = CLIENT_ID,
    client_secret = CLIENT_SECRET,
    redirect_uri = REDIRECT_URI,
    scope = scope))

def get_episodes(query):
    try:
        offset = 0
        limit = 50
        episode_features_list = [
            "name",
            "release_date",
            "tag_new",
            "external_urls",
            "duration_ms",
            "type",
            "id",
            # <extension data>
            # "audio_preview_url",
            # "description",
            # "html_description",
            # "images",
        ]
        episode_df = pd.DataFrame(columns=episode_features_list)
        today = DT.date.today()
        two_week_ago = today - DT.timedelta(days = 14)
        while True:
            results = sp.search(q=quote(query), type='episode', offset=offset, limit=limit)
            for item in results['episodes']['items']:
                # 创建空字典
                episode_features = {}
               

<details>
<summary>英文:</summary>

The [`Search for Item`](https://developer.spotify.com/documentation/web-api/reference/search) API has no sort option.

So you have to sort at the client side by your own logic.

You did not specify the language option.
I made a demo code by `node.js`

#### Demo Code
```node.js
const express = require(&quot;express&quot;)
const axios = require(&#39;axios&#39;)
const cors = require(&quot;cors&quot;)
const fs = require(&#39;fs&#39;)

const app = express()
app.use(cors())

// Credential
CLIENT_ID = &quot;&lt;your Client ID&gt;&quot;
CLIENT_SECRET = &quot;&lt;your Client Secret&gt;&quot;
PORT = 3000 // it is located in Spotify dashboard&#39;s Redirect URIs, my port is 3000, should be replace your Port
REDIRECT_URI = `http://localhost:${PORT}/callback` // my case is &#39;http://localhost:3000/callback&#39;
SCOPE = [
    &#39;user-read-private&#39;
]

// Get Access Token
const getToken = async (code) =&gt; {
    try {
        const resp = await axios.post(
            url = &#39;https://accounts.spotify.com/api/token&#39;,
            data = new URLSearchParams({
                &#39;grant_type&#39;: &#39;authorization_code&#39;,
                &#39;redirect_uri&#39;: REDIRECT_URI,
                &#39;code&#39;: code
            }),
            config = {
                headers: {
                    &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39;
                },
                auth: {
                    username: CLIENT_ID,
                    password: CLIENT_SECRET
                }
            })
        return Promise.resolve(resp.data.access_token);
    } catch (err) {
        console.error(err)
        return Promise.reject(err)
    }
}

// Get Episodes by query
const getEpisodes = async (token, query) =&gt; {
    try {
        let offset = 0
        let next = 1
        const limit = 50;
        const episodes = [];

        const encodeString = encodeURI(query)
        while (next != null) {
            const resp = await axios.get(
                url = `https://api.spotify.com/v1/search?q=${encodeString}&amp;type=episode&amp;limit=${limit}&amp;offset=${offset}`,
                config = {
                    headers: {
                        &#39;Content-Type&#39;: &#39;application/json&#39;,
                        &#39;Authorization&#39;: `Bearer ${token}`,
                    }
                })
            for(const item of resp.data.episodes.items) {
                if(item?.name != null) {
                    episodes.push({
                        name: item.name,
                        release_date: item.release_date,
                        external_urls: item.external_urls.spotify,
                        duration_ms: item.duration_ms,
                        type: item.type,
                        id : item.id,
                        // &lt;extension data&gt;
                        // audio_preview_url: item.audio_preview_url,
                        // description: item.description,
                        // html_description: item.html_description,
                        // images : item.images,
                    })
                }
            }
            offset = offset + limit
            next = resp.data.episodes.next
        }
        // After sort by release date
        return Promise.resolve(episodes.sort((a,b) =&gt; Date.parse(b.release_date) - Date.parse(a.release_date)));
    } catch (err) {
        console.error(err)
        return Promise.reject(err)
    }
}

// login URL
app.get(&quot;/login&quot;, (request, response) =&gt; {
    const redirect_url = `https://accounts.spotify.com/authorize?response_type=code&amp;client_id=${CLIENT_ID}&amp;scope=${SCOPE}&amp;state=123456&amp;redirect_uri=${REDIRECT_URI}&amp;prompt=consent`
    response.redirect(redirect_url);
})

// Call back URL
app.get(&quot;/callback&quot;, async (request, response) =&gt; {
    const code = request.query[&quot;code&quot;]
    getToken(code)
        .then(access_token =&gt; {
            getEpisodes(access_token,&quot;tim ferriss&quot;)
                .then(episodes =&gt; {
                    // For file save
                    const data = JSON.stringify(episodes);
                    fs.writeFileSync(&#39;simple_results.json&#39;, data);

                    // For browser displaying 
                    return response.send({
                        &#39;Total episodes length: &#39;: episodes.length,
                        &#39;Episodes&#39;: episodes
                    });
                })

        })
        .catch(error =&gt; {
            console.log(error.message);
        })
})


// start express server
app.listen(PORT, () =&gt; {
    console.log(`Listening on :${PORT}`)
})

Install dependencies

npm install axios express cors fs

Run the server

node demo.js

Login and Get Episodes

The port number should be match your port number.

http://localhost:3000/user

Result

在Spotify API中搜索播客剧集时获取最新结果

If you want to see full data, remove commend-out code in getEpisodes()

episodes.push({
name: item.name,
release_date: item.release_date,
external_urls: item.external_urls.spotify,
duration_ms: item.duration_ms,
type: item.type,
id : item.id,
// &lt;extension data&gt;
audio_preview_url: item.audio_preview_url,
description: item.description,
html_description: item.html_description,
images : item.images,
})

Update - added Python demo

Save as get-episodes.py file name.

import spotipy
from spotipy.oauth2 import SpotifyOAuth
import pandas as pd
from urllib.parse import quote
import numpy as np
import datetime as DT

# Set your Spotify API credentials as environment variables, it will pick by spotipy API
CLIENT_ID = &quot;9d53d43408c04c089e58f6b615f44bf9&quot;
CLIENT_SECRET = &quot;96f14dc115644d83b8957b77fcface31&quot;
PORT = 3000
REDIRECT_URI = &quot;http://localhost:{0}/callback&quot;.format(PORT)

# Just this scope good enough to get user_recently_played API
scope = &quot;user-read-recently-played&quot;

# This API call raise web browser and ask user login for getting callback with Authorization Code flow
sp = spotipy.Spotify(auth_manager=SpotifyOAuth(
    client_id = CLIENT_ID,
    client_secret = CLIENT_SECRET,
    redirect_uri = REDIRECT_URI,
    scope = scope))

def get_episodes(query):
    try:
        offset = 0
        limit = 50
        episode_features_list = [
            &quot;name&quot;,
            &quot;release_date&quot;,
            &quot;tag_new&quot;,
            &quot;external_urls&quot;,
            &quot;duration_ms&quot;,
            &quot;type&quot;,
            &quot;id&quot;,
            # &lt;extension data&gt;
            # &quot;audio_preview_url&quot;,
            # &quot;description&quot;,
            # &quot;html_description&quot;,
            # &quot;images&quot;,
        ]
        episode_df = pd.DataFrame(columns=episode_features_list)
        today = DT.date.today()
        two_week_ago = today - DT.timedelta(days = 14)
        while True:
            results = sp.search(q=quote(query), type=&#39;episode&#39;, offset=offset, limit=limit)
            for item in results[&#39;episodes&#39;][&#39;items&#39;]:
                # Create empty dictionary
                episode_features = {}
                # Get metadata
                episode_features[&quot;name&quot;] = item[&quot;name&quot;]
                episode_features[&quot;release_date&quot;] =  pd.to_datetime(item[&quot;release_date&quot;], format=&#39;%Y-%m-%d&#39;)
                episode_features[&#39;tag_new&#39;] = np.where(episode_features[&quot;release_date&quot;] &gt;= pd.to_datetime(two_week_ago, format=&#39;%Y-%m-%d&#39;), True, False)
                episode_features[&quot;external_urls&quot;] = item[&quot;external_urls&quot;][&quot;spotify&quot;]
                episode_features[&quot;duration_ms&quot;] = item[&quot;duration_ms&quot;]
                episode_features[&quot;type&quot;] = item[&quot;type&quot;]
                episode_features[&quot;id&quot;] = item[&quot;id&quot;]
                # Concatenate the data frames
                item_df = pd.DataFrame(episode_features, index=[0])
                episode_df = pd.concat([episode_df, item_df], ignore_index=True)
            # Increment offset by the limit for the next API call
            offset += limit
            next = results[&#39;episodes&#39;][&#39;next&#39;]
            if next is None:
                break
        return episode_df
    except Exception as e:
        print(&#39;Failed to upload to call get_episodes(): &#39;+ str(e))

episodes = get_episodes(&quot;tim ferriss&quot;)
sorted_episodes = episodes.sort_values(by=&#39;release_date&#39;, ascending = False)
print(sorted_episodes)

Run the python demo

python get-episodes.py

Python Result

在Spotify API中搜索播客剧集时获取最新结果

huangapple
  • 本文由 发表于 2023年7月18日 03:00:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76707395.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定