我正在尝试使用 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)
这些更改所做的操作是:
-
简化了
get_num_of_songs
: 当找到匹配的播放列表时,该函数现在直接返回歌曲总数。 -
使用
while True
循环持续提取歌曲: 这确保了在收到所有歌曲之前,代码将继续发出请求。 -
检查每个请求中的项目数:
如果响应中的项目数小于
limit
,则表示我们已到达播放列表的末尾,并且循环中断。
使用这种方法,的代码应该能够可靠地检索播放列表中的所有歌曲,而无论其大小如何。
标签:python,spotify,webapi From: 78799718