CoolFace
Apppublic

wldmr/transcriptifier-st-hf7

sourceHugging Facecc-by-nc-3.0updated 3y agoView on Hugging Face
0likes
yt_stats.py160 linesDownload Raw Back to root
1import json2import requests3from tqdm import tqdm4import isodate5 6class YTstats:7 8    def __init__(self, api_key):9        self.api_key = api_key10        self.channel_statistics = None11        self.video_data = None12 13    def extract_all(self, channel_id):14        self.get_channel_statistics(channel_id)15        self.get_channel_video_data(channel_id)16 17    def get_channel_statistics(self, channel_id):18        """Extract the channel statistics"""19        print('get channel statistics...')20        url = f'https://www.googleapis.com/youtube/v3/channels?part=statistics&id={channel_id}&key={self.api_key}'21        #pbar = tqdm(total=1)22        23        json_url = requests.get(url)24        data = json.loads(json_url.text)25        try:26            data = data['items'][0]['statistics']27        except KeyError:28            print('Could not get channel statistics')29            data = {}30 31        self.channel_statistics = data32        #pbar.update()33        #pbar.close()34        return data35 36    def get_channel_video_data(self, channel_id, df_sheet, loading_bar, progress_text, item_limit=3):37        "Extract all video information of the channel"38        print('get video data...')39        channel_videos, channel_playlists = self._get_channel_content(channel_id, limit=50)40 41        channel_videos_out = dict()42 43        total_items = len(channel_videos)44        item = 045        step_size=046        step=047        if total_items!=0:48            step_size=round(1/total_items,4)49        #step = step_size50        parts=["snippet", "statistics","contentDetails", "topicDetails"]51        for video_id in tqdm(channel_videos):52            if item == item_limit:53                break54            55            loading_bar.progress(step, text=progress_text)56 57            for part in parts:58                data = self._get_single_video_data(video_id, part)59                channel_videos[video_id].update(data)60            61            duration = isodate.parse_duration(channel_videos[video_id]['duration'])62            short_duration = isodate.parse_duration('PT4M')63 64            if duration > short_duration and video_id not in list(df_sheet.ID):65                item = item+166                step = step +step_size67                channel_videos_out[video_id] = channel_videos[video_id]68                69 70        step=1.071        loading_bar.progress(step, text=progress_text)72        self.video_data = channel_videos_out73        74 75    def _get_single_video_data(self, video_id, part):76        """77        Extract further information for a single video78        parts can be: 'snippet', 'statistics', 'contentDetails', 'topicDetails'79        """80 81        url = f"https://www.googleapis.com/youtube/v3/videos?part={part}&id={video_id}&key={self.api_key}"82        json_url = requests.get(url)83        data = json.loads(json_url.text)84        try:85            data = data['items'][0][part]86        except KeyError as e:87            print(f'Error! Could not get {part} part of data: \n{data}')88            data = dict()89        return data90 91    def _get_channel_content(self, channel_id, limit=None, check_all_pages=True):92        """93        Extract all videos and playlists, can check all available search pages94        channel_videos = videoId: title, publishedAt95        channel_playlists = playlistId: title, publishedAt96        return channel_videos, channel_playlists97        """98        url = f"https://www.googleapis.com/youtube/v3/search?key={self.api_key}&channelId={channel_id}&part=snippet,id&order=date"99        if limit is not None and isinstance(limit, int):100            url += "&maxResults=" + str(limit)101 102        vid, pl, npt = self._get_channel_content_per_page(url)103        idx = 0104        while(check_all_pages and npt is not None and idx < 10):105            nexturl = url + "&pageToken=" + npt106            next_vid, next_pl, npt = self._get_channel_content_per_page(nexturl)107            vid.update(next_vid)108            pl.update(next_pl)109            idx += 1110 111        return vid, pl112 113    def _get_channel_content_per_page(self, url):114        """115        Extract all videos and playlists per page116        return channel_videos, channel_playlists, nextPageToken117        """118        json_url = requests.get(url)119        data = json.loads(json_url.text)120        channel_videos = dict()121        channel_playlists = dict()122        if 'items' not in data:123            print('Error! Could not get correct channel data!\n', data)124            return channel_videos, channel_videos, None125 126        nextPageToken = data.get("nextPageToken", None)127 128        item_data = data['items']129        for item in item_data:130            try:131                kind = item['id']['kind']132                published_at = item['snippet']['publishedAt']133                title = item['snippet']['title']134                if kind == 'youtube#video':135                    video_id = item['id']['videoId']136                    channel_videos[video_id] = {'publishedAt': published_at, 'title': title}137                elif kind == 'youtube#playlist':138                    playlist_id = item['id']['playlistId']139                    channel_playlists[playlist_id] = {'publishedAt': published_at, 'title': title}140            except KeyError as e:141                print('Error! Could not extract data from item:\n', item)142 143        return channel_videos, channel_playlists, nextPageToken144 145    def dump(self, channel_id):146        """Dumps channel statistics and video data in a single json file"""147        if self.channel_statistics is None or self.video_data is None:148            print('data is missing!\nCall get_channel_statistics() and get_channel_video_data() first!')149            return150 151        fused_data = {channel_id: {"channel_statistics": self.channel_statistics,152                              "video_data": self.video_data}}153 154        channel_title = self.video_data.popitem()[1].get('channelTitle', channel_id)155        channel_title = channel_title.replace(" ", "_").lower()156        filename = channel_title + '.json'157        with open(filename, 'w') as f:158            json.dump(fused_data, f, indent=4)159        160        print('file dumped to', filename)