首页 > 编程问答 >尝试使用 Spotify API 获取播放列表中超过 100 首歌曲的所有歌曲

尝试使用 Spotify API 获取播放列表中超过 100 首歌曲的所有歌曲

时间:2024-07-27 05:08:48浏览次数:15  
标签:python spotify webapi

我正在尝试使用 Spotify API 返回指定播放列表中的歌曲名称列表。我能够让它返回 100 多首歌曲,但每次都会短一些看似随机的数量。在一个包含 222 首歌曲的播放列表上,它只返回 214 首歌曲,在另一个包含 152 首歌曲的播放列表上,它只返回 125 首歌曲。

这是我正在努力解决的代码:

@app.route("/bloom_songs")
def display_songs():

    id = "4AOXvSwX0XGg1cOPZxCa0t"
    # tracks.extend(data.get("items", []))
    lists = display_songs(id)

    return lists  # jsonify(lists)


def get_num_of_songs(id):
    if "access_token" not in session:
        return redirect("/login")

    if datetime.now().timestamp() > session["expires_at"]:
        return redirect("/refresh-token")

    headers = {"Authorization": f"Bearer {session['access_token']}"}

    response = requests.get(API_BASE_URL + "me/playlists", headers=headers)

    playlists = response.json()

    for playlist in playlists["items"]:
        if playlist["id"] == id:
            total_songs = int(playlist["tracks"]["total"])

    return total_songs


def display_songs(id):

    if "access_token" not in session:
        return redirect("/login")

    if datetime.now().timestamp() > session["expires_at"]:
        return redirect("/refresh-token")

    headers = {"Authorization": f"Bearer {session['access_token']}"}

    total_songs = get_num_of_songs(id)

    loop_times = 100
    total_requests = math.ceil(total_songs / loop_times)

    song_names = []

    i = 0
    while i < total_requests:
        try:
            response = requests.get(
                f"{API_BASE_URL}playlists/{id}/tracks?limit={loop_times}&offset={i*loop_times}",
                headers=headers,
            )
            data = response.json()

            # Check if the response contains items
            if "items" in data:
                for song in data["items"]:
                    song_names.append(song["track"]["name"])
                i += 1
            else:
                song_names.append("error")
               
        except Exception as e:
            print(f"Error fetching data: {e}")
            break

    song_names_json = json.dumps(song_names)

    return song_names_json

我尝试制作我要求的歌曲数量较小的看看这是否会增加它的精确度,但它只是返回相同结果的速度较慢。一般来说,我对编程还很陌生,很抱歉,如果这是一个愚蠢的问题,但答案很明显,但我在网上找不到任何东西。


该问题源于对循环的处理以及当请求返回的项目少于 limit 时代码的假设。不必将 total_songs 除以 limit 并提前计算请求,而应该持续请求歌曲,直到收到所有歌曲。

以下是对的代码进行修复的方法:

@app.route("/bloom_songs")
def display_songs():
    id = "4AOXvSwX0XGg1cOPZxCa0t"
    lists = display_songs(id)
    return lists 

def get_num_of_songs(id):
    if "access_token" not in session:
        return redirect("/login")

    if datetime.now().timestamp() > session["expires_at"]:
        return redirect("/refresh-token")

    headers = {"Authorization": f"Bearer {session['access_token']}"}
    response = requests.get(API_BASE_URL + "me/playlists", headers=headers)
    playlists = response.json()

    for playlist in playlists["items"]:
        if playlist["id"] == id:
            return playlist["tracks"]["total"]

    return 0  

def display_songs(id):
    if "access_token" not in session:
        return redirect("/login")

    if datetime.now().timestamp() > session["expires_at"]:
        return redirect("/refresh-token")

    headers = {"Authorization": f"Bearer {session['access_token']}"}
    song_names = []
    offset = 0
    limit = 100  

    while True:
        response = requests.get(
            f"{API_BASE_URL}playlists/{id}/tracks?limit={limit}&offset={offset}",
            headers=headers,
        )
        data = response.json()

        # Check if the response contains items
        if "items" in data:
            for song in data["items"]:
                song_names.append(song["track"]["name"])

            # If no more items are returned, break the loop
            if len(data["items"]) < limit:
                break

            offset += limit
        else:
            print("Error fetching data or no more items")
            break 

    return json.dumps(song_names)

这些更改所做的操作是:

  1. 简化了 get_num_of_songs 当找到匹配的播放列表时,该函数现在直接返回歌曲总数。
  2. 使用 while True 循环持续提取歌曲: 这确保了在收到所有歌曲之前,代码将继续发出请求。
  3. 检查每个请求中的项目数: 如果响应中的项目数小于 limit ,则表示我们已到达播放列表的末尾,并且循环中断。

使用这种方法,的代码应该能够可靠地检索播放列表中的所有歌曲,而无论其大小如何。

标签:python,spotify,webapi
From: 78799718

相关文章

  • 使用特定的Python版本(MacOS)制作virtualenv
    我安装了brew,python3(默认和最新版本)和pip3,pyenv。TensorFlow现在不支持python3.7,所以我听说我应该制作一个独立运行3.6或更低版本的virtualenv。我安装了python3.6.7bypyenvinstall3.6.7但无法制作virtualenv-p3.6.7(mydir)因为3.6.7不在P......
  • 使用Python去除图像中的线条
    我正在尝试使用Python和cv2、numpy、skimage等从黑白图像中删除“阴影线”(如果图像中存在“阴影线”)。本质上,我的图像可以有1或2条曲线,如下例所示。但每条线都有一条1-5像素外的阴影线,需要删除。我怎样才能在Python中做到这一点?原始......
  • Python 和 OpenCV:如何裁剪半成形边界框
    我有一个为无网格表创建网格线的脚本:脚本之前:脚本之后:是否有一种简单的方法,使用OpenCV来裁剪“脚本之后”图像,使其仅包含四边边界框?示例输出:编辑:我目前正在研究一种解决方案,该解决方案可以找到垂直/水平方向的第一条/最后一条......
  • 使用类型提示将 Python 转换为 Cython
    类型提示现在在Python3.5版本中可用。在规范(PEP484)中,目标(和非目标)被明确暴露:#RationaleandGoals此PEP旨在为类型注释提供标准语法,开放Python代码更容易静态分析和重构、潜在的运行时类型检查以及(也许在某些情况下)利用类型信息生成代码。......
  • 在 Python 类型提示中区分 PySpark 和 Pandas DataFrame (PyCharm)
    在PyCharm中,如果使用apyspark.sql.DataFrame代替pandas.DataFrame,类型提示似乎不会触发警告,反之亦然。例如以下代码根本不会生成任何警告:frompyspark.sqlimportDataFrameasSparkDataFramefrompandasimportDataFrameasPandasDataFramedef......
  • 如何在Python中继承类型提示?
    所以我的问题是,当我有一个A类型的类来做事情并且我使用这些函数作为subclass(B)时,它们仍然是类A的类型,并且不接受我的类B对象作为参数或作为函数签名。我的问题简化了:fromtypingimportTypeVar,Generic,CallableT=TypeVar('T'......
  • Python - 如何传递类对象的函数参数类型(打字)
    我想python3.7附带了(不确定),不仅可以将变量名传递给函数,还可以传递变量的类型。我想知道的是是否有可能传递特定类的类型。以同样的方式传递:deffoo_func(i:int)->None:pass如果我有一个类,让我们说:classfoo_class(object):pass我如何转换fo......
  • 使用 Python 构建简单 REST API
    使用Python构建简单RESTAPI1.概述本技术文档旨在指导开发者使用Python框架Flask构建一个基本的RESTAPI。通过学习本指南,您将掌握创建、读取、更新和删除(CRUD)操作的基本知识,并能够使用Python构建自己的API。2.安装依赖首先,您需要确保已安装Python和Flask......
  • Python——Pandas(第二讲)
    文章目录变量类型的转换Pandas支持的数据类型在不同数据类型间转换建立索引新建数据框时建立索引读入数据时建立索引指定某列为索引列将索引还原变量列引用和修改索引引用索引修改索引修改索引名修改索引值更新索引Series的索引和切片DataFrame的索引和切片选择列按......
  • 基于Python+Django的红色文化研学网站设计与实现
    ......