def search_view(request, q, max_results): """ 在youtube上搜索关键字q,返回结果数设置为max_results :param request: :param q: :param max_results: :return: """ #youtube = get_authenticated_service(request.user) youtube = get_authenticated_service_s2s() search_response = youtube.search().list(q=q, part="id,snippet", maxResults=max_results).execute() videos = [] channels = [] playlists = [] # Add each result to the appropriate list, and then display the lists of # matching videos, channels, and playlists. for search_result in search_response.get("items", []): if search_result["id"]["kind"] == "youtube#video": videos.append("%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["videoId"])) elif search_result["id"]["kind"] == "youtube#channel": channels.append("%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["channelId"])) elif search_result["id"]["kind"] == "youtube#playlist": playlists.append("%s (%s)" % (search_result["snippet"]["title"], search_result["id"]["playlistId"])) return render_to_response('result.html', {'list': videos})
def my_watchlater_lists_view(request, max_results): """ 获取认证用户的watchlater列表 参考: https://developers.google.com/youtube/v3/docs/playlistItems/list#try-it :param request: :param max_results: :return: """ #youtube = get_authenticated_service(request.user) youtube = get_authenticated_service_s2s() myproxy = httplib2.ProxyInfo(proxy_type=httplib2.socks.PROXY_TYPE_SOCKS5, proxy_host='127.0.0.1', proxy_port=8115) myhttp = httplib2.Http(proxy_info=myproxy) # Retrieve the contentDetails part of the channel resource for the # authenticated user's channel. # 通过channels查询认证用户的contentDetails里的relatedPlaylists的watchLater channels_response = youtube.channels().list( mine=True, part="contentDetails").execute(http=myhttp) for channel in channels_response["items"]: # From the API response, extract the playlist ID that identifies the # list # of videos uploaded to the authenticated user's channel. watchLater_list_id = channel["contentDetails"]["relatedPlaylists"][ "watchLater"] # Retrieve the list of watchLater videos in the authenticated user's # channel. # fields 的设置参考 https://developers.google.com/youtube/v3/getting # -started#partial playlistitems_list_request = youtube.playlistItems().list( playlistId=watchLater_list_id, part="snippet", maxResults=max_results, fields="items(id,snippet/title)") # 参考 http://stackoverflow.com/a/31795605/1314124 res = playlistitems_list_request.execute() nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.playlistItems().list( part="snippet", playlistId=watchLater_list_id, maxResults=max_results, pageToken=nextPageToken).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] return render_to_response('result.html', {'list': res['items']})
def get_my_subscribe_channel_view(request): """ 获取认证用户订阅的频道channel的信息 同一个google账号有两个用户名的,选择不同的用户名,返回的订阅信息也不一样 :param request: :return: """ max_results = 10 #youtube = get_authenticated_service(request.user) youtube = get_authenticated_service_s2s() res = youtube.subscriptions().list(part='snippet', mine=True, maxResults=max_results).execute() # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.subscriptions().list( part='snippet', mine=True, maxResults=max_results, pageToken=nextPageToken ).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] subscriptions_list = [] for result in res.get("items", []): subscriptions_list.append(result['snippet']) for subscription in subscriptions_list: channel, created = YouTubeChannel.objects.update_or_create( channel_id=subscription['resourceId']['channelId'], defaults={'title': subscription['title'], 'description': subscription['description'], 'thumbnail': subscription['thumbnails']['default']['url'] } ) return render_to_response('result.html', {'list': subscriptions_list, 'text': res["pageInfo"]["totalResults"]})
def my_homepage_subscription_view(request, max_results): """ 获取认证用户的youtube首页显示的订阅频道信息,显示出来,但是不保存 https://developers.google.com/youtube/v3/docs/activities/list#errors :param request: :return: """ #youtube = get_authenticated_service(request.user) youtube = get_authenticated_service_s2s() if youtube: # 如果youtube.activities().list().execute(http=myhttp)使用以下代理则会提示错误: # "Daily Limit for Unauthenticated Use Exceeded. Continued use # requires signup." # myproxy = httplib2.ProxyInfo( # proxy_type=httplib2.socks.PROXY_TYPE_SOCKS5, # proxy_host='127.0.0.1', proxy_port=8115) # myhttp = httplib2.Http(proxy_info=myproxy) # home: This parameter can only be used in a properly authorized # request. # Set this # parameter's value to true to retrieve the activity feed that # displays on # the YouTube home page for the currently authenticated user. response = youtube.activities().list(part='snippet', home=True, maxResults=max_results).execute() homepage_subscription_list = [] else: return render_to_response('result.html', {'text': '获取google youtube服务失败,未能查询到结果'}) for result in response.get("items", []): if result['snippet']["type"] == 'upload': homepage_subscription_list.append(result['snippet']["title"]) else: # https://developers.google.com/youtube/v3/docs/activities # https://developers.google.com/youtube/v3/docs/activities # #snippet.type # 有的type没有title continue return render_to_response('result.html', {'list': homepage_subscription_list})
def get_youtube_channel_info(channel_id): """ 根据channel_id,获取channel的信息,并保存到数据库中 https://developers.google.com/youtube/v3/docs/channels/list#try-it GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails %2Csnippet&id=UCEQpJTOXGkvS1UQsdCm6lLA&key={YOUR_API_KEY} :param channel_id: :param user: :return: """ #youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() if youtube: res = youtube.channels().list( part='snippet', id=channel_id).execute() else: return False # channel_info_list = [] # for result in res.get("items", []): # channel_info_list.append(result['snippet']) channel_info = res.get("items", [])[0]['snippet'] channel, created = YouTubeChannel.objects.update_or_create( channel_id=channel_id, defaults={'title': channel_info['title'], 'description': channel_info['description'], 'thumbnail': channel_info['thumbnails']['default']['url'] } ) return channel_info
def get_youtube_channel_info(channel_id): """ 根据channel_id,获取channel的信息,并保存到数据库中 https://developers.google.com/youtube/v3/docs/channels/list#try-it GET https://www.googleapis.com/youtube/v3/channels?part=contentDetails %2Csnippet&id=UCEQpJTOXGkvS1UQsdCm6lLA&key={YOUR_API_KEY} :param channel_id: :param user: :return: """ #youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() if youtube: res = youtube.channels().list(part='snippet', id=channel_id).execute() else: return False # channel_info_list = [] # for result in res.get("items", []): # channel_info_list.append(result['snippet']) channel_info = res.get("items", [])[0]['snippet'] channel, created = YouTubeChannel.objects.update_or_create( channel_id=channel_id, defaults={ 'title': channel_info['title'], 'description': channel_info['description'], 'thumbnail': channel_info['thumbnails']['default']['url'] }) return channel_info
def get_youtube_playlist_video_info(youtube_playlist_id, max_results): """ 获取youtube_playlist_id的所有video的信息 :param youtube_playlist_id: :param max_results:最大为50 :param user: :return: https://developers.google.com/apis-explorer/#p/youtube/v3/youtube .playlistItems.list """ # filter()返回的是一个list,就算只有一个结果 playlist = YouTubePlaylist.objects.filter( playlist_id=youtube_playlist_id).first() #youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() if youtube: res = youtube.playlistItems().list( part='snippet, contentDetails', playlistId=youtube_playlist_id, maxResults=max_results).execute() # 将该playlist包含的视频数量保存到YouTubePlaylist中 if res: video_num = res['pageInfo']['totalResults'] playlist.video_num = video_num playlist.save(update_fields=['video_num']) else: return False # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.playlistItems().list( part='snippet, contentDetails', playlistId=youtube_playlist_id, maxResults=max_results, pageToken=nextPageToken ).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] video_list = [] for result in res.get("items", []): # 查询看该视频所属的channel是否保存到了数据库中 channel = YouTubeChannel.objects.filter( channel_id=result['snippet']["channelId"]).first() # 如果视频所属的channel保存在YouTubeChannel中,并且is_download属性为true # 也就是只下载已经保存到YouTubeChannel中的channel的视频 if channel and channel.is_download: video = { 'video_id': result['contentDetails']["videoId"], 'title': result['snippet']["title"], 'publishedAt': result['snippet']["publishedAt"], 'thumbnail': result['snippet']['thumbnails']['default']['url'], 'channel': channel, 'playlist': playlist } # publishedAt 为ISO 8601 ( # YYYY-MM-DDThh:mm:ss.sZ)格式,类似2008-09-26T01:51:42.000Z d = dateutil.parser.parse(video['publishedAt']) # 将获取到的playlist的视频信息保存到数据库的Video model中 youtube_video, created = Video.objects.update_or_create( video_id=video['video_id'], defaults={'title': video['title'], 'publishedAt': d, 'thumbnail': video['thumbnail'], 'channel': channel, 'playlist': video['playlist'] } ) video_list.append(video) return video_list
def get_youtube_playlist_info(youtube_channel_id, max_results, user): # 获取channel中的用户自定义的youtube playlist的信息并保存到数据中 # https://developers.google.com/youtube/v3/docs/playlists/list#parameters # GET https://www.googleapis.com/youtube/v3/playlists?part=snippet # &channelId=UCEQpJTOXGkvS1UQsdCm6lLA&key={YOUR_API_KEY} #youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() if youtube: res = youtube.playlists().list( part='snippet', channelId=youtube_channel_id, maxResults=max_results).execute() else: return False # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.playlists().list( part='snippet', channelId=youtube_channel_id, # maxResults=int(max_results), pageToken=nextPageToken ).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] youtube_playlist_list = [] for result in res.get("items", []): # 查询看该视频所属的channel是否保存到了数据库中 channel = YouTubeChannel.objects.filter( channel_id=result['snippet']["channelId"]).first() # 如果视频所属的channel保存在YouTubeChannel中, # 也就是只下载已经保存到YouTubeChannel中的channel的playlist if channel: playlist = { 'playlist_id': result['id'], 'title': result['snippet']["title"], 'channel': channel, 'description': result['snippet']["description"], 'thumbnail': result['snippet']['thumbnails']['default']['url'] } d = dateutil.parser.parse(result['snippet']['publishedAt']) youtube_playlist, created = \ YouTubePlaylist.objects.update_or_create( playlist_id=playlist['playlist_id'], defaults={'title': playlist['title'], 'publishedAt': d, 'thumbnail': playlist['thumbnail'], 'channel': channel } ) youtube_playlist_list.append(playlist) return youtube_playlist_list
def get_multi_youtube_video_info(): """ 一次获取max_results个保存在Video model中的youtube视频的时长,播放数等额外信息 :param user: :param max_results: <50 :return: """ video_list = Video.need_get_video_info.order_by('-publishedAt')[:50] video_id_list = [] for video in video_list: video_id_list.append(video.video_id) video_id_string = ', '.join(video_id_list) #youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() # https://developers.google.com/youtube/v3/docs/videos/list res = youtube.videos().list( part="contentDetails, snippet, statistics", id=video_id_string ).execute() # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.videos().list( part="contentDetails, snippet, statistics", id=video_id_string, pageToken=nextPageToken ).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] # 从返回的对象里找出type为upload的 youtube_video_id_list = [] for result in res.get("items", []): video = Video.objects.get(pk=result['id']) # 某些youtube视频没有tags # 比如 https://www.youtube.com/watch?v=_Po6DWVPbmQ # 如果没有tags,则返回'',这样json.dumps(tags_list)的结果就是'' # video model的tags是TEXTField,''就是其空值 tags_list = result['snippet'].get('tags', '') video.tags = json.dumps(tags_list) # https://docs.djangoproject.com/en/1.6/ref/models/instances # /#specifying-which-fields-to-save video.view_count = result['statistics'].get('viewCount', 0) # 某些youtube视频没有likeCount # 比如 https://www.youtube.com/watch?v=YiTAEQNFI4A video.like_count = result['statistics'].get('likeCount', 0) # 将list转成json的格式保存到数据库中 # http://stackoverflow.com/a/16743442/1314124 duration = isodate.parse_duration(result['contentDetails']['duration']) video.duration = duration.total_seconds() video.save( update_fields=['view_count', 'like_count', 'tags', 'duration']) youtube_video_id_list.append(result['id']) return youtube_video_id_list
def get_youtube_playlist_video_info(youtube_playlist_id, max_results): """ 获取youtube_playlist_id的所有video的信息,并保存到数据库中 :param youtube_playlist_id: :param max_results:最大为50 :param user: :return: https://developers.google.com/apis-explorer/#p/youtube/v3/youtube .playlistItems.list """ # filter()返回的是一个list,就算只有一个结果 playlist = YouTubePlaylist.objects.filter( playlist_id=youtube_playlist_id).first() # youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() if youtube: res = youtube.playlistItems().list( part='snippet, contentDetails', playlistId=youtube_playlist_id, maxResults=max_results).execute() # 将该playlist包含的视频数量保存到YouTubePlaylist中 if res: video_num = res['pageInfo']['totalResults'] playlist.video_num = video_num playlist.save(update_fields=['video_num']) else: result_text = '获取youtube的认证失败' return False, result_text # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.playlistItems().list( part='snippet, contentDetails', playlistId=youtube_playlist_id, maxResults=max_results, pageToken=nextPageToken ).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] video_list = [] for result in res.get("items", []): # 查询看该视频所属的channel是否保存到了数据库中 channel = YouTubeChannel.objects.filter( channel_id=result['snippet']["channelId"]).first() # 如果视频所属的channel保存在YouTubeChannel中,并且is_download属性为true # 也就是只下载已经保存到YouTubeChannel中的channel的视频 if channel: if channel.is_download: video = { 'video_id': result['contentDetails']["videoId"], 'title': result['snippet']["title"], 'publishedAt': result['snippet']["publishedAt"], 'thumbnail': result['snippet']['thumbnails']['default'][ 'url'], 'channel': channel, 'playlist': playlist } # publishedAt 为ISO 8601 ( # YYYY-MM-DDThh:mm:ss.sZ)格式,类似2008-09-26T01:51:42.000Z d = dateutil.parser.parse(video['publishedAt']) # 将获取到的playlist的视频信息保存到数据库的Video model中 youtube_video, created = Video.objects.update_or_create( video_id=video['video_id'], defaults={'title': video['title'], 'publishedAt': d, 'thumbnail': video['thumbnail'], 'channel': channel, 'playlist': video['playlist'] } ) video_list.append(video) else: result = False result_text = 'youtube_playlist_id为 {' \ 'youtube_playlist_id}对应的channel的is_download属性设置为false'.format( youtube_playlist_id=youtube_playlist_id) else: result = False result_text = '在数据库中无法查找到 youtube_playlist_id为 {youtube_playlist_id}' \ '对应的channel'.format( youtube_playlist_id=youtube_playlist_id) result_text = 'YouTube Playlist为{youtube_playlist_id}的视频已保存'.format( youtube_playlist_id=youtube_playlist_id) return video_list, result_text
def get_youtube_playlist_info(youtube_channel_id, max_results, user): # 获取channel中的用户自定义的youtube playlist的信息并保存到数据中 # https://developers.google.com/youtube/v3/docs/playlists/list#parameters # GET https://www.googleapis.com/youtube/v3/playlists?part=snippet # &channelId=UCEQpJTOXGkvS1UQsdCm6lLA&key={YOUR_API_KEY} # youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() if youtube: res = youtube.playlists().list( part='snippet', channelId=youtube_channel_id, maxResults=max_results).execute() else: return False # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.playlists().list( part='snippet', channelId=youtube_channel_id, # maxResults=int(max_results), pageToken=nextPageToken ).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] youtube_playlist_list = [] for result in res.get("items", []): # 查询看该视频所属的channel是否保存到了数据库中 channel = YouTubeChannel.objects.filter( channel_id=result['snippet']["channelId"]).first() # 如果视频所属的channel保存在YouTubeChannel中, # 也就是只下载已经保存到YouTubeChannel中的channel的playlist if channel: playlist = { 'playlist_id': result['id'], 'title': result['snippet']["title"], 'channel': channel, 'description': result['snippet']["description"], 'thumbnail': result['snippet']['thumbnails']['default']['url'] } d = dateutil.parser.parse(result['snippet']['publishedAt']) youtube_playlist, created = \ YouTubePlaylist.objects.update_or_create( playlist_id=playlist['playlist_id'], defaults={'title': playlist['title'], 'publishedAt': d, 'thumbnail': playlist['thumbnail'], 'channel': channel } ) youtube_playlist_list.append(playlist) return youtube_playlist_list
def get_multi_youtube_video_info(): """ 一次获取max_results个保存在Video model中的youtube视频的时长,播放数等额外信息 :param user: :param max_results: <50 :return: """ video_list = Video.need_get_video_info.order_by('-publishedAt')[:50] video_id_list = [] for video in video_list: video_id_list.append(video.video_id) video_id_string = ', '.join(video_id_list) #youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() # https://developers.google.com/youtube/v3/docs/videos/list res = youtube.videos().list(part="contentDetails, snippet, statistics", id=video_id_string).execute() # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.videos().list( part="contentDetails, snippet, statistics", id=video_id_string, pageToken=nextPageToken).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] # 从返回的对象里找出type为upload的 youtube_video_id_list = [] for result in res.get("items", []): video = Video.objects.get(pk=result['id']) # 某些youtube视频没有tags # 比如 https://www.youtube.com/watch?v=_Po6DWVPbmQ # 如果没有tags,则返回'',这样json.dumps(tags_list)的结果就是'' # video model的tags是TEXTField,''就是其空值 tags_list = result['snippet'].get('tags', '') video.tags = json.dumps(tags_list) # https://docs.djangoproject.com/en/1.6/ref/models/instances # /#specifying-which-fields-to-save video.view_count = result['statistics'].get('viewCount', 0) # 某些youtube视频没有likeCount # 比如 https://www.youtube.com/watch?v=YiTAEQNFI4A video.like_count = result['statistics'].get('likeCount', 0) # 将list转成json的格式保存到数据库中 # http://stackoverflow.com/a/16743442/1314124 duration = isodate.parse_duration(result['contentDetails']['duration']) video.duration = duration.total_seconds() video.save( update_fields=['view_count', 'like_count', 'tags', 'duration']) youtube_video_id_list.append(result['id']) return youtube_video_id_list
def get_subscription_update_video(user, max_results): """ 获取认证用户的youtube首页显示的订阅频道的视频信息,保存到本地数据库 https://developers.google.com/youtube/v3/docs/activities/list#errors :param request: max_results:最大为50 :return: """ #youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() # home: This parameter can only be used in a properly # authorized request. Set this # parameter's value to true to retrieve the activity feed that displays on # the YouTube home page for the currently authenticated user. # home=True 获取登陆用户的首页推荐视频 # mine=True 获取登陆用户进行like,upload等操作的视频 # home和mine 不能同时为True,否者会提示错误 if youtube: res = youtube.activities().list(part='snippet, contentDetails', home=True, maxResults=max_results).execute() else: return False # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.activities().list( part='snippet, contentDetails', home=True, maxResults=max_results, pageToken=nextPageToken).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] # 从返回的对象里找出type为upload的 video_list = [] for result in res.get("items", []): # 查询看该视频所属的channel是否保存到了数据库中 channel = YouTubeChannel.objects.filter( channel_id=result['snippet']["channelId"]).first() #如果视频所属的channel保存在YouTubeChannel中,并且is_download属性为true if channel and channel.is_download: # 如果该视频所属的频道 is_download 属性被设置为True,才进行下载 # todo 待测试 if result['snippet']["type"] == 'upload': video = { 'video_id': result['contentDetails']["upload"]["videoId"], 'title': result['snippet']["title"], 'publishedAt': result['snippet']["publishedAt"], 'thumbnail': result['snippet']['thumbnails']["default"]["url"], 'channel': result['snippet']["channelId"] } import datetime, dateutil.parser # publishedAt 为ISO 8601 ( # YYYY-MM-DDThh:mm:ss.sZ)格式,类似2008-09-26T01:51:42.000Z d = dateutil.parser.parse(video['publishedAt']) youtube_video, created = Video.objects.update_or_create( video_id=video['video_id'], defaults={ 'title': video['title'], 'publishedAt': d, 'thumbnail': video['thumbnail'], 'channel': channel }) video_list.append(video) else: # https://developers.google.com/youtube/v3/docs/activities # https://developers.google.com/youtube/v3/docs/activities # #snippet.type # 有的type没有title continue return video_list
def get_subscription_update_video(user, max_results): """ 获取认证用户的youtube首页显示的订阅频道的视频信息,保存到本地数据库 https://developers.google.com/youtube/v3/docs/activities/list#errors :param request: max_results:最大为50 :return: """ #youtube = get_authenticated_service(user) youtube = get_authenticated_service_s2s() # home: This parameter can only be used in a properly # authorized request. Set this # parameter's value to true to retrieve the activity feed that displays on # the YouTube home page for the currently authenticated user. # home=True 获取登陆用户的首页推荐视频 # mine=True 获取登陆用户进行like,upload等操作的视频 # home和mine 不能同时为True,否者会提示错误 if youtube: res = youtube.activities().list( part='snippet, contentDetails', home=True, maxResults=max_results).execute() else: return False # 循环获取完所有的结果 nextPageToken = res.get('nextPageToken') while ('nextPageToken' in res): nextPage = youtube.activities().list( part='snippet, contentDetails', home=True, maxResults=max_results, pageToken=nextPageToken ).execute() res['items'] = res['items'] + nextPage['items'] if 'nextPageToken' not in nextPage: res.pop('nextPageToken', None) else: nextPageToken = nextPage['nextPageToken'] # 从返回的对象里找出type为upload的 video_list = [] for result in res.get("items", []): # 查询看该视频所属的channel是否保存到了数据库中 channel = YouTubeChannel.objects.filter( channel_id=result['snippet']["channelId"]).first() #如果视频所属的channel保存在YouTubeChannel中,并且is_download属性为true if channel and channel.is_download: # 如果该视频所属的频道 is_download 属性被设置为True,才进行下载 # todo 待测试 if result['snippet']["type"] == 'upload': video = { 'video_id': result['contentDetails']["upload"]["videoId"], 'title': result['snippet']["title"], 'publishedAt': result['snippet']["publishedAt"], 'thumbnail': result['snippet']['thumbnails']["default"][ "url"], 'channel': result['snippet']["channelId"] } import datetime, dateutil.parser # publishedAt 为ISO 8601 ( # YYYY-MM-DDThh:mm:ss.sZ)格式,类似2008-09-26T01:51:42.000Z d = dateutil.parser.parse(video['publishedAt']) youtube_video, created = Video.objects.update_or_create( video_id=video['video_id'], defaults={'title': video['title'], 'publishedAt': d, 'thumbnail': video['thumbnail'], 'channel': channel } ) video_list.append(video) else: # https://developers.google.com/youtube/v3/docs/activities # https://developers.google.com/youtube/v3/docs/activities # #snippet.type # 有的type没有title continue return video_list