YouTube API videos.rate 方法只对一些视频进行评分

问题描述 投票:0回答:1

代码摘要:使用 YouTube API 并实现 OAuth 2.0 的脚本可以访问一个帐户,检索其喜欢的视频,并访问另一个帐户并使用该喜欢的视频列表在新帐户上喜欢它们。这看起来像是一个奇怪的项目,但我这周才开始使用 Python,这是我的第一个项目,它看起来很简单(我错了)

这是我代码的相关部分:

def likeVideos(videos,youtubeObject):

    youtube = youtubeObject
    videos = videos
    numofVideosLiked = 0
    numLikedVideos = 0

    for video in videos:
        numLikedVideos += 1

    for video in videos:
        newRequest = youtube.videos().getRating(
            id=[video['id']]
        )

        newResponse = newRequest.execute()

        if 'rating' in newResponse and (newResponse['rating'] == 'like' or newResponse['rating'] == 'unspecified'):
            print(f"Already liked '{video['snippet']['title']}' or something went wrong...")
        else:
            likeRequest = youtube.videos().rate(
                id=video['id'],
                rating='like'
            ).execute()

            numofVideosLiked += 1
            print(f"Liking {video['snippet']['title']}...{numofVideosLiked}/{numLikedVideos}")

终端的输出显示我成功点赞了父账号的前194个视频,然后崩溃了:

Liking coding in c until my program is unsafe...191/354
Liking OVERDOSING ON TF2!!!...192/354
Liking JavaScript Fighting Game Tutorial with HTML Canvas...193/354
Liking DIY PCBs At Home (Single Sided Presensitized)...194/354

然而,孩子号只有30视频真正被点赞,并且是按5的随机间隔点赞的。 (具体来说,视频 1-5、31-35、68-72、106-110 等在第二个帐户上实际上 喜欢)我的理解是列表阅读是 5 组,所以你需要增加maxResults 参数就像我最初检索列表时所做的那样:

while True:
    # Make API request
    request = youtube.videos().list(
        part='snippet',
        myRating='like',
        maxResults=50,
        pageToken = next_page_token
    )

    response = request.execute()

    # Add videos to list
    videos += response['items']

    next_page_token = response.get('nextPageToken')
    if not next_page_token:
        break

但是我不确定在实际调用 rate() 函数来喜欢视频时该怎么做,因为它的唯一参数是 id 和 rating.

我相信这个代码块是主要问题:

if 'rating' in newResponse and (newResponse['rating'] == 'like' or newResponse['rating'] == 'unspecified'):
            print(f"Already liked '{video['snippet']['title']}' or something went wrong...")
        else:
            likeRequest = youtube.videos().rate(
                id=video['id'],
                rating='like'
            ).execute()

在某些视频已经被点赞并且点赞视频的方法似乎不准确后,当我多次运行脚本时,if 语句永远不会捕捉到已经被点赞的视频。

  • Youtube 是否可能限制您喜欢视频的速度?有解决方法吗?
  • 除了这个代码片段之外,还有什么更好的方法来检查视频是否已经被点赞?:
    if 'rating' in newResponse and (newResponse['rating'] == 'like' or newResponse['rating'] == 'unspecified'):

只有在需要帮助解决我的问题时,才提供完整的源代码:

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
import pickle
import os

# Make API request and build Youtube object
def getYoutubeObject(client_secret, path_to_pickled_file):
    
    credentials = None
    scopes = ["https://www.googleapis.com/auth/youtube.force-ssl",
          'https://www.googleapis.com/auth/youtube',
          'https://www.googleapis.com/auth/youtube.readonly',
          'https://www.googleapis.com/auth/youtube.upload',
          'https://www.googleapis.com/auth/youtubepartner',
          'https://www.googleapis.com/auth/youtubepartner-channel-audit']
    
    # path_to_pickled_file file stores user credentials
    if os.path.exists(path_to_pickled_file):
        print("Loading credentials of account from file...")
        with open(path_to_pickled_file, 'rb') as token:
            credentials = pickle.load(token)

    # If there are no valid credentials, refresh token or log in
    if not credentials or not credentials.valid:
        if credentials and credentials.expired and credentials.refresh_token:
            print("Refreshing access token for account...")
            credentials.refresh(Request())
        else:
            print("Fetching new tokens for account...")
            flow = InstalledAppFlow.from_client_secrets_file(
                client_secret, 
                scopes=scopes
            )
            flow.run_local_server(
                port=8080, 
                prompt="consent", 
                authorization_prompt_message=''
                )
            credentials = flow.credentials

            # Save credentials for next use
            with open(path_to_pickled_file, 'wb') as f:
                print("Saving credentials of account for future use...")
                pickle.dump(credentials, f)

    api_name = 'youtube'
    api_version = 'v3'

    youtube = build(api_name, api_version, credentials=credentials)

    return youtube

# Return list of liked videos
def getLikedVideos(youtubeObject):

    youtube = youtubeObject
    next_page_token = None
    videos = []
    # fields = "id, snippet(title)"

    while True:
        # Make API request
        request = youtube.videos().list(
            part='snippet',
            myRating='like',
            maxResults=50,
            pageToken = next_page_token
        )

        response = request.execute()

        # Add videos to list
        videos += response['items']

        next_page_token = response.get('nextPageToken')
        if not next_page_token:
            break

    numLikedVideos = 0

    for video in videos:
        numLikedVideos += 1

    print(f"You have {numLikedVideos} likes videos!")
    input("Press Enter to continue...")

    return videos

def likeVideos(videos,youtubeObject):

    youtube = youtubeObject
    videos = videos
    numofVideosLiked = 0
    numLikedVideos = 0

    for video in videos:
        numLikedVideos += 1

    for video in videos:
        newRequest = youtube.videos().getRating(
            id=[video['id']]
        )

        newResponse = newRequest.execute()

        if 'rating' in newResponse and (newResponse['rating'] == 'like' or newResponse['rating'] == 'unspecified'):
            print(f"Already liked '{video['snippet']['title']}' or something went wrong...")
        else:
            likeRequest = youtube.videos().rate(
                id=video['id'],
                rating='like'
            ).execute()

            numofVideosLiked += 1
            print(f"Liking {video['snippet']['title']}...{numofVideosLiked}/{numLikedVideos}")

def main():
    client_secret = 'client_secret.json'
    path_to_pickled_file = 'token.pickle'
    path_to_second_pickled_file = 'secondToken.pickle'

    input("Press Enter to retrieve first Youtube object...")
    youtube = getYoutubeObject(client_secret, path_to_pickled_file)

    input("Press Enter to get liked videos...")
    videos = getLikedVideos(youtube)

    input("Press Enter to retrieve second Youtube object...")
    newYtObj = getYoutubeObject(client_secret, path_to_second_pickled_file)

    input("Press Enter to like videos...")
    likeVideos(videos, newYtObj)

main()

我尝试使用 videos.rate 方法为列表(350 多个项目)中的所有视频点赞。但是,实际上只有 30 个最终被评分(从我喜欢的视频历史中按时间顺序排列的 5 个间隔。前 5 个被喜欢,然后 25 个视频之后它再次起作用并喜欢另外 5 个,等等)

python google-api youtube-api google-api-python-client
1个回答
0
投票

使用

import time
,你可以像这样包含
time.sleep(time_interval_in_seconds)

def likeVideos(videos,youtubeObject):

    youtube = youtubeObject
    videos = videos
    numofVideosLiked = 0
    numLikedVideos = 0

    for video in videos:
        numLikedVideos += 1

    for video in videos:
        newRequest = youtube.videos().getRating(
            id=[video['id']]
        )

        newResponse = newRequest.execute()

        if 'rating' in newResponse and (newResponse['rating'] == 'like' or newResponse['rating'] == 'unspecified'):
            print(f"Already liked '{video['snippet']['title']}' or something went wrong...")
        else:
            likeRequest = youtube.videos().rate(
                id=video['id'],
                rating='like'
            ).execute()

            numofVideosLiked += 1
            print(f"Liking {video['snippet']['title']}...{numofVideosLiked}/{numLikedVideos}")
            time.sleep(1.5)

问题不是代码。问题是 YouTube API 对您请求某些数据的速度有限制。

© www.soinside.com 2019 - 2024. All rights reserved.