使用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,maxResults=50,mine=True
        )
        response = request.execute()

        playlists = [Playlist(item['id'],item['snippet']['title']) for item in response['items']]

        return playlists

解决方法

函数right的参数playlist_id应该是播放列表的ID(因为它已传递给playlistId API端点的参数PlaylistItems.list)。

但是,通过代码:

get_videos_from_playlist

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...