Skip to content

Instantly share code, notes, and snippets.

@vr2262
Last active December 14, 2015 23:59
Show Gist options
  • Save vr2262/5169756 to your computer and use it in GitHub Desktop.
Save vr2262/5169756 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"metadata": {
"name": "youtube_api_demo"
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This hosted notebook is current as of March 14. Run it yourself to bring it up to date!"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import gdata.youtube\n",
"import gdata.youtube.service\n",
"from datetime import timedelta"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 1
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"yt_service = gdata.youtube.service.YouTubeService()"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 2
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It seems a feed gives you 25 results at a time no matter what."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_playlists = yt_service.Query('http://gdata.youtube.com/feeds/api/users/GameGrumps/playlists?v=2')"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 3
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_playlists.__dict__"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 4,
"text": [
"{'_GDataFeed__generator': <atom.Generator at 0x1d4b090>,\n",
" '_GDataFeed__id': <atom.Id at 0x1cc1d90>,\n",
" 'author': [<atom.Author at 0x1d4b050>],\n",
" 'category': [<atom.Category at 0x1cdbb90>],\n",
" 'contributor': [],\n",
" 'entry': [<gdata.GDataEntry at 0x1d4b250>,\n",
" <gdata.GDataEntry at 0x1d4b290>,\n",
" <gdata.GDataEntry at 0x1d4b850>,\n",
" <gdata.GDataEntry at 0x1d4bed0>,\n",
" <gdata.GDataEntry at 0x1d4e550>,\n",
" <gdata.GDataEntry at 0x1d4eb90>,\n",
" <gdata.GDataEntry at 0x1d53210>,\n",
" <gdata.GDataEntry at 0x1d53850>,\n",
" <gdata.GDataEntry at 0x1d53e90>,\n",
" <gdata.GDataEntry at 0x1d56510>,\n",
" <gdata.GDataEntry at 0x1d56b50>,\n",
" <gdata.GDataEntry at 0x1d591d0>,\n",
" <gdata.GDataEntry at 0x1d59810>,\n",
" <gdata.GDataEntry at 0x1d59e50>,\n",
" <gdata.GDataEntry at 0x1d5c4d0>,\n",
" <gdata.GDataEntry at 0x1d5cb10>,\n",
" <gdata.GDataEntry at 0x1d60190>,\n",
" <gdata.GDataEntry at 0x1d607d0>,\n",
" <gdata.GDataEntry at 0x1d60e10>,\n",
" <gdata.GDataEntry at 0x1d654d0>,\n",
" <gdata.GDataEntry at 0x1d65b50>,\n",
" <gdata.GDataEntry at 0x1d681d0>,\n",
" <gdata.GDataEntry at 0x1d68810>,\n",
" <gdata.GDataEntry at 0x1d68e90>,\n",
" <gdata.GDataEntry at 0x1d6d510>],\n",
" 'extension_attributes': {},\n",
" 'extension_elements': [],\n",
" 'icon': None,\n",
" 'items_per_page': <gdata.ItemsPerPage at 0x1d4b210>,\n",
" 'link': [<atom.Link at 0x1cdbd10>,\n",
" <atom.Link at 0x1cdbd90>,\n",
" <atom.Link at 0x1cdbe10>,\n",
" <atom.Link at 0x1cdbe90>,\n",
" <atom.Link at 0x1cdbf10>,\n",
" <atom.Link at 0x1cdbf90>],\n",
" 'logo': <atom.Logo at 0x1cdbcd0>,\n",
" 'rights': None,\n",
" 'start_index': <gdata.StartIndex at 0x1d4b1d0>,\n",
" 'subtitle': None,\n",
" 'text': None,\n",
" 'title': <atom.Title at 0x1cdbc50>,\n",
" 'total_results': <gdata.TotalResults at 0x1d4b190>,\n",
" 'updated': <atom.Updated at 0x1cc1dd0>}"
]
}
],
"prompt_number": 4
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_playlists.entry[0].title.text"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 5,
"text": [
"'The Great Circus Mystery Starring Mickey & Minnie'"
]
}
],
"prompt_number": 5
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_playlists.entry[0].content.text"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 6,
"text": [
"\"Arin and Jon have a grand ol' time playing The Great Circus Mystery Starring Mickey & Minnie on the SNES!\""
]
}
],
"prompt_number": 6
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"playlist_url = yt_service.GetYouTubePlaylistEntry(grump_playlists.entry[0].link[2].href)\n",
"playlist_videos = yt_service.GetYouTubePlaylistVideoFeed(playlist_url.feed_link[0].href)\n",
"for entry in playlist_videos.entry:\n",
" print entry.title.text"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"The Great Circus Mystery Starring Mickey & Minnie: Topsy-Turvy - PART 1 - Game Grumps\n",
"The Great Circus Mystery Starring Mickey & Minnie: Jungle Jangle - PART 2- Game Grumps\n"
]
}
],
"prompt_number": 7
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_playlists.link[5].__dict__\n",
"# Note 'rel': 'next'"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 8,
"text": [
"{'extension_attributes': {},\n",
" 'extension_elements': [],\n",
" 'href': 'https://gdata.youtube.com/feeds/api/users/GameGrumps/playlists?start-index=26&max-results=25',\n",
" 'hreflang': None,\n",
" 'length': None,\n",
" 'rel': 'next',\n",
" 'text': None,\n",
" 'title': None,\n",
" 'type': 'application/atom+xml'}"
]
}
],
"prompt_number": 8
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"more_playlist = grump_playlists.link[5].href\n",
"yt_service.Query(more_playlist).entry[0].content.text"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 9,
"text": [
"\"Arin and Jon play Demon's Souls and probably die a lot.\""
]
}
],
"prompt_number": 9
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that you can only get up to 50 video results at a time. Seems `<link rel = 'next' ...>` can help."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_uploads = yt_service.GetYouTubeVideoFeed(\n",
" 'http://gdata.youtube.com/feeds/api/users/GameGrumps/uploads?max-results=5&startindex=0&v=2')"
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 10
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_uploads.__dict__"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 11,
"text": [
"{'_GDataFeed__generator': <atom.Generator at 0x1cdb110>,\n",
" '_GDataFeed__id': <atom.Id at 0x1ccb6d0>,\n",
" 'author': [<atom.Author at 0x1cdb0d0>],\n",
" 'category': [<atom.Category at 0x1d74990>],\n",
" 'contributor': [],\n",
" 'entry': [<gdata.youtube.YouTubeVideoEntry at 0x1cdb390>,\n",
" <gdata.youtube.YouTubeVideoEntry at 0x1cdb690>,\n",
" <gdata.youtube.YouTubeVideoEntry at 0x1d84610>,\n",
" <gdata.youtube.YouTubeVideoEntry at 0x1d6e0d0>,\n",
" <gdata.youtube.YouTubeVideoEntry at 0x1d6ead0>],\n",
" 'extension_attributes': {},\n",
" 'extension_elements': [],\n",
" 'icon': None,\n",
" 'items_per_page': <gdata.ItemsPerPage at 0x1cdb490>,\n",
" 'link': [<atom.Link at 0x1d74890>,\n",
" <atom.Link at 0x1d747d0>,\n",
" <atom.Link at 0x1d74790>,\n",
" <atom.Link at 0x1cdb890>,\n",
" <atom.Link at 0x1cdba50>,\n",
" <atom.Link at 0x1cdb190>],\n",
" 'logo': <atom.Logo at 0x1d748d0>,\n",
" 'rights': None,\n",
" 'start_index': <gdata.StartIndex at 0x1cdb450>,\n",
" 'subtitle': None,\n",
" 'text': None,\n",
" 'title': <atom.Title at 0x1d74910>,\n",
" 'total_results': <gdata.TotalResults at 0x1cdb350>,\n",
" 'updated': <atom.Updated at 0x1ccb690>}"
]
}
],
"prompt_number": 11
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_uploads.entry[0].title.text"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 12,
"text": [
"'The Great Circus Mystery Starring Mickey & Minnie: Ghastly Ghouls - PART 3 - Game Grumps'"
]
}
],
"prompt_number": 12
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print grump_uploads.entry[0].content.text"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Their method of flight continues to distress and confound.\n",
"\n",
"Game Grumps are:\n",
"\n",
"Egoraptor: http://www.YouTube.com/Egoraptor\n",
"\n",
"JonTron: http://www.YouTube.com/Jontronshow\n",
"\n",
"\n",
"Game Grumps on Facebook: https://www.facebook.com/GameGrumps\n",
"\n",
"Game Grumps on Twitter: https://www.twitter.com/gamegrumps\n",
"\n",
"Game Grumps Store: http://www.sharkrobot.com/game-grumps\n"
]
}
],
"prompt_number": 13
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_uploads.entry[0].media.duration.seconds"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 14,
"text": [
"'608'"
]
}
],
"prompt_number": 14
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_uploads.entry[0].rating.__dict__"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 15,
"text": [
"{'average': '4.8586087',\n",
" 'extension_attributes': {'rel': 'http://schemas.google.com/g/2005#overall'},\n",
" 'extension_elements': [],\n",
" 'max': '5',\n",
" 'min': '1',\n",
" 'num_raters': '877',\n",
" 'text': None}"
]
}
],
"prompt_number": 15
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"grump_uploads.entry[0].statistics.view_count"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "pyout",
"prompt_number": 16,
"text": [
"'303'"
]
}
],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's find out how much time the Grumps have spent playing Sonic 2006."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"# Of course, first we have to find the Sonic 2006 playlist...\n",
"possible_sonic_playlist_chunk = grump_playlists\n",
"sonic_not_found = True\n",
"pages = 0\n",
"while sonic_not_found:\n",
" pages += 1\n",
" for index, entry in enumerate(possible_sonic_playlist_chunk.entry):\n",
" if 'sonic' in entry.title.text.lower():\n",
" sonic_not_found = False\n",
" break\n",
" else:\n",
" possible_sonic_playlist_chunk = yt_service.Query(possible_sonic_playlist_chunk.link[5].href)\n",
"sonic_playlist_url = yt_service.GetYouTubePlaylistEntry(possible_sonic_playlist_chunk.entry[index].link[2].href)\n",
"sonic_playlist = yt_service.GetYouTubePlaylistVideoFeed(sonic_playlist_url.feed_link[0].href)\n",
"print 'We found the {} playlist after {} pages of playlist results. '\\\n",
" 'It is playlist #{} on this page.'.format(entry.title.text, pages, index + 1)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"We found the Sonic '06 playlist after 2 pages of playlist results. It is playlist #3 on this page.\n"
]
}
],
"prompt_number": 17
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Sonic 2006 playlist is also longer than 25 videos so we need to recycle some of our approach."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"total_duration = 0 # Measured in seconds.\n",
"number_of_episodes = 0\n",
"while sonic_playlist.link[4].rel == 'next':\n",
" for entry in sonic_playlist.entry:\n",
" number_of_episodes += 1\n",
" # Each Game Grumps episode has a 5 second intro\n",
" total_duration += float(entry.media.duration.seconds) - 5\n",
" sonic_playlist = yt_service.GetYouTubePlaylistVideoFeed(sonic_playlist.link[4].href)\n",
"print 'Game time (not taking speedups into account): ' + \\\n",
" str(timedelta(seconds=total_duration)) + ' (hours:minutes:seconds)'"
],
"language": "python",
"metadata": {},
"outputs": [
{
"output_type": "stream",
"stream": "stdout",
"text": [
"Game time (not taking speedups into account): 4:37:15 (hours:minutes:seconds)\n"
]
}
],
"prompt_number": 18
},
{
"cell_type": "code",
"collapsed": false,
"input": [],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 18
}
],
"metadata": {}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment