Created
July 16, 2024 19:32
-
-
Save 0187773933/5feece94216631fd565c038f13897f67 to your computer and use it in GitHub Desktop.
Gets YouTube Channels Latest Videos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import sys | |
import json | |
# pip install google-api-python-client | |
from googleapiclient.discovery import build | |
from pprint import pprint | |
import isodate | |
api_service_name = "youtube" | |
api_version = "v3" | |
api_key = "asdf" | |
youtube = build( api_service_name , api_version , developerKey=api_key ) | |
def get_channel_id(channel_name): | |
request = youtube.search().list( | |
part="snippet", | |
q=channel_name, | |
type="channel", | |
maxResults=1 | |
) | |
response = request.execute() | |
if 'items' in response and len(response['items']) > 0: | |
return response['items'][0]['id']['channelId'] | |
else: | |
return None | |
def get_video_details(video_ids): | |
request = youtube.videos().list( | |
part="contentDetails", | |
id=",".join(video_ids) | |
) | |
response = request.execute() | |
return response['items'] | |
def get_channel_videos(channel_id, max_results=300): | |
videos = [] | |
next_page_token = None | |
while len(videos) < max_results: | |
request = youtube.search().list( | |
part="snippet", | |
channelId=channel_id, | |
maxResults=min(max_results - len(videos), 50), | |
pageToken=next_page_token, | |
order="date" | |
) | |
response = request.execute() | |
video_ids = [item['id']['videoId'] for item in response['items'] if item['id']['kind'] == 'youtube#video'] | |
video_details = get_video_details(video_ids) | |
for item, detail in zip(response['items'], video_details): | |
if item['id']['kind'] == 'youtube#video': | |
duration = isodate.parse_duration(detail['contentDetails']['duration']).total_seconds() | |
# Exclude shorts (videos with a duration less than 60 seconds) | |
if duration > 90: | |
videos.append({ | |
'videoId': item['id']['videoId'], | |
'title': item['snippet']['title'], | |
'publishedAt': item['snippet']['publishedAt'], | |
'duration': duration | |
}) | |
next_page_token = response.get('nextPageToken') | |
if not next_page_token: | |
break | |
return videos[:max_results] | |
def write_json( file_path , python_object ): | |
with open( file_path , 'w', encoding='utf-8' ) as f: | |
json.dump( python_object , f , ensure_ascii=False , indent=4 ) | |
def read_json( file_path ): | |
with open( file_path ) as f: | |
return json.load( f ) | |
def write_text( file_path , text_lines_list ): | |
with open( file_path , 'w', encoding='utf-8' ) as f: | |
f.writelines( text_lines_list ) | |
def read_text( file_path ): | |
with open( file_path ) as f: | |
return f.read().splitlines() | |
channel_name = sys.argv[ 1 ] | |
channel_id = get_channel_id( channel_name ) | |
print( f"Channel ID: {channel_id}" ) | |
videos = get_channel_videos( channel_id ) | |
write_json( f"{channel_name}.json" , videos ) | |
text_lines = [] | |
for video in videos: | |
yt_url = f"https://www.youtube.com/watch?v={video['videoId']}" | |
text_lines.append( f"{yt_url}\n" ) | |
text_lines[ -1 ] = text_lines[ -1 ].strip() | |
write_text( f"{channel_name}.txt" , text_lines ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment