python - 使用 Python 和 Youtube API 自动化 Spotify - 错误 403:请求缺少有效的 API 密钥
问题描述
我正在这里做一个项目,它会抓取我的 YouTube 帐户播放列表,然后将每首歌曲添加到我的 Spotify 喜欢的歌曲中。这是我第一个使用 Python 和 API 的项目,所以在这里我可能听起来很困惑。
运行程序后,我正在使用我的 google OAUTH Client 2.0 进行身份验证。我输入他们在验证后给我的新密钥,然后选择我想从中获取歌曲的播放列表。
然后,一旦我选择了要使用的播放列表,就会出现我的问题。然后执行停止并在 request.execute() 调用后给我这个错误:
"googleapiclient.errors.HttpError: <HttpError 404 when requesting https://www.googleapis.com/youtube/v3/playlistItems?playlistId=%3Cyoutube_client.Playlist+object+at+0x0000028A3C883948%3E&part=id%2C+snippet&maxResults=50&alt=json returned "The playlist identified with the request's <code>playlistId</code> parameter cannot be found.">
当我单击链接时,会出现此消息:
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"errors": [
{
"message": "The request is missing a valid API key.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
这是执行停止的代码:
def get_videos_from_playlist(self, playlist_id):
songs = []
request = self.youtube_client.playlistItems().list(
playlistId=playlist_id,
part="id, snippet",
maxResults=50
)
response = request.execute()
我很困惑它在哪里询问我缺少的 API,但我正在使用 Google OAUTH 2.0 客户端进行身份验证。我想如果我有另一个,我就不需要一个。我需要两者吗?我需要在客户端机密中添加一些内容吗?
编辑
这是我的 run.py 中调用的样子:
def run():
#1. Get a list of our playlists from Youtube
youtube_client = YouTubeClient('./creds/secrets.json')
spotify_client = SpotifyClient(os.getenv('SPOTIFY_AUTH_TOKEN'))
playlists = youtube_client.get_playlists()
#2. Ask which playlist we want to get the music videos from
for index, playlist in enumerate(playlists):
print(f"{index}: {playlist.title}")
choice = int(input("Enter your choice: "))
chosen_playlist = playlists[choice]
print(f"You selected: {chosen_playlist.title}")
#3 For each video in the playlist, get the song information from Youtube
songs = youtube_client.get_videos_from_playlist(chosen_playlist)
print(f"Attempting to add {len(songs)}")
这是我的 youtube_client.py:
def __init__(self, credentials_location):
# youtube_dl default User-Agent can cause some json values to return as None, using Facebook's web crawler solves this.
youtube_dl.utils.std_headers['User-Agent'] = "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)"
scopes = ["https://www.googleapis.com/auth/youtube.readonly"]
# Disable OAuthlib's HTTPS verification when running locally.
# *DO NOT* leave this option enabled in production.
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
api_service_name = "youtube"
api_version = "v3"
# Get credentials and create an API client
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
credentials_location, scopes)
credentials = flow.run_console()
youtube_client = googleapiclient.discovery.build(
api_service_name, api_version, credentials=credentials)
self.youtube_client = youtube_client
def get_playlists(self):
request = self.youtube_client.playlists().list(
part="id, snippet",
maxResults=50,
mine=True
)
response = request.execute()
playlists = [Playlist(item['id'], item['snippet']['title']) for item in response['items']]
return playlists
解决方案
playlist_id
function的参数get_videos_from_playlist
应该是播放列表的 ID(因为它被传递到 API 端点的参数playlistId
)PlaylistItems.list
。
但是,通过代码:
songs = youtube_client.get_videos_from_playlist(
chosen_playlist)
的实际类型playlist_id
是类Playlist
(上面的代码没有显示)。
您必须通过将类实例get_videos_from_playlist
保留的 ID 传递给它来修复您的调用。chosen_playlist
Playlist
如果您的Playlist
课程类似于:
class Playlist:
def __init__(self, id, title):
self.id = id
self.title = title
那么您的固定代码将如下所示:
songs = youtube_client.get_videos_from_playlist(
chosen_playlist.id)
推荐阅读
- javascript - 获取文本以说出消息的持续时间(javascript、SpeechSynthesisUtterance、chrome)
- java - 递归函数返回数字中位数的平均值
- java - 如何更改 Swagger 文档中的日期格式?
- vhdl - VHDL在我的顶级实体中使用实例化实体的输出
- javascript - React JS:能够检测浏览器中的切换选项卡
- c++ - 有没有办法区分 Qt 小部件是通过鼠标单击还是从表格按键获得焦点?
- javascript - Brush and Zoom d3
- angular - PrimeNG DropDown 自动删除连续空格
- .net - 诊断源的 NLog 诊断侦听器
- python - 我的应用程序在 python 中启动后,如何在 pyqt5 的另一个窗口中打开图像?