英文:
YouTube API videos.rate method only rates some 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=]
)
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}")
如果您需要进一步的帮助,请随时提出您的问题。
英文:
Code summary: Script that uses YouTube API and implements OAuth 2.0 to get access to one account, retrieve its liked videos, and get access to another account and use that list of liked videos to like them on the new account. It may seem like a weird project but I just started using Python this week and this is my first project and it seemed easy enough (I was wrong)
This is the relevant part of my code:
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=]
)
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}")
The output in the terminal indicated that I successfully liked my first 194 videos from the parent account before it broke down:
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
However, the child account only had 30 videos actually liked, and they were done in random intervals of 5. (To be specific, videos 1-5, 31-35, 68-72, 106-110, etc were actually liked on the second account) My understanding is that reading from lists is in groups of 5 so you need to increase the maxResults parameter like I did here when retrieving the list initially:
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
But I am not sure what to do when actually calling the rate() function to like the videos because its only parameters are id and rating.
I believe this code block is the main problem:
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()
The if statement never catches already-liked videos when I run the script multiple times after some videos were already liked and the method of liking the videos doesn't seem to be accurate.
- Is it possible Youtube limits how fast you can like videos? Is there a workaround?
- What is a better way to check if the videos are already liked other than this code snippet?:
if 'rating' in newResponse and (newResponse['rating'] == 'like' or newResponse['rating'] == 'unspecified'):
Here is the full source code only if it's necessary to help with my question:
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=]
)
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()
I tried liking all videos within a list (350+ items) using the videos.rate method. But, only 30 ended up actually being rated (In intervals of 5 chronologically from my liked video history. The first 5 were liked, then 25 videos later it worked again and liked 5 more, etc)
答案1
得分: 2
使用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=]
)
newResponse = newRequest.execute()
if 'rating' in newResponse and (newResponse['rating'] == 'like' or newResponse['rating'] == 'unspecified'):
print(f"已经喜欢 '{video['snippet']['title']}' 或发生了错误...")
else:
likeRequest = youtube.videos().rate(
id=video['id'],
rating='like'
).execute()
numofVideosLiked += 1
print(f"喜欢 {video['snippet']['title']}...{numofVideosLiked}/{numLikedVideos}")
time.sleep(1.5)
问题不在于代码,而在于YouTube API 对于请求某些数据的速度限制。
英文:
Using import time
, you can include time.sleep(time_interval_in_seconds)
like such:
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=]
)
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)
The issue is not the code. The issue is the limit the YouTube API has on how fast you can request certain data.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论