Google Data API
Google Data APIを使ってYouTubeのプレイリスト作成や動画登録を行う.Pythonから操作するためにgdata-python-clientが用意されている.このサイトからダウンロードした gdata-...zip を解凍したら
sudo python setup.py install
でインストール.
使い方は
Developer's Guide: Python - YouTube — Google Developers
APIキーの取得
http://code.google.com/apis/youtube/dashboard/でAPIキーを取得する.
ClientLogin
ローカルで動かすのでClientLoginで認証する.認証はPlaylistの作成や動画の登録に必要.下記のスクリプトでは以下の部分を設定する.YouTubeのアカウント名は http://www.youtube.com/user/stmct だったらstmctにあたるところ.Googleを2段階認証にしている場合はアプリケーション固有のパスワードを生成する.
username = 'YouTubeのアカウント名' email = 'APIキーを取得したGoogleのアカウント名' password = 'Googleのパスワード' developer_key = '取得したAPIキー'
コード
使い方
python youtube_gdata_create_playlist.py http://...
汚いコードだな…
This file contains 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 python | |
# -*- coding:utf-8 -*- | |
''' | |
まとめサイトなどURLに含まれるYouTubeをプレイリストに保存する | |
$ python youtube_gdata_playlist.py http://... | |
''' | |
# 以下要設定 | |
# cf. YouTubeクライアント | |
# https://developers.google.com/youtube/1.0/developers_guide_python#ClientLogin | |
#### | |
username = '' | |
email = '' | |
password = '' | |
developer_key = '' | |
#### | |
import sys | |
import time | |
import re | |
import urllib2 | |
import gdata.youtube | |
import gdata.youtube.service | |
from BeautifulSoup import BeautifulSoup | |
class YouTube(object): | |
""" | |
YouTube Data API | |
https://code.google.com/p/gdata-python-client/ | |
https://developers.google.com/youtube/1.0/developers_guide_python | |
""" | |
def __init__(self, username, email, password, developer_key): | |
self.yt_service = gdata.youtube.service.YouTubeService() | |
self.yt_service.ssl = True | |
self.username = username | |
# ClientLogin for installed applications | |
self.yt_service.email = email | |
self.yt_service.password = password | |
self.yt_service.developer_key = developer_key | |
self.yt_service.ProgrammaticLogin() | |
def AddPlaylist(self, title, description=""): | |
''' | |
プレイリストを追加する | |
https://developers.google.com/youtube/1.0/developers_guide_python#AddingPlaylists | |
Parameters | |
========== | |
- title : str | |
- description : str | |
Returns | |
======= | |
playlist_uri : str | |
''' | |
# タイトルと説明を表示 | |
limit = 0 | |
for i in range(len(title)): | |
if limit > 60: | |
break | |
if ord(title[i]) > 255: | |
limit += 3 | |
else: | |
limit += 1 | |
tmp_title = title[:i] if i != len(title) - 1 else title | |
print title # 20字 | |
print description | |
new_public_playlistentry = self.yt_service.AddPlaylist(tmp_title, description) | |
if isinstance(new_public_playlistentry, gdata.youtube.YouTubePlaylistEntry): | |
print 'New playlist added' | |
return 'http://gdata.youtube.com/feeds/playlists/' + new_public_playlistentry.id.text.split('/')[-1] | |
else: | |
return None | |
def AddVideoToPlaylist(self, playlist_uri, video_id): | |
''' | |
プレイリストにビデオを追加する | |
Parameters | |
========== | |
- playlist_uri : str | |
- video_id : str | |
''' | |
playlist_video_entry = self.yt_service.AddPlaylistVideoEntryToPlaylist( | |
playlist_uri, video_id) | |
if isinstance(playlist_video_entry, gdata.youtube.YouTubePlaylistVideoEntry): | |
print video_id | |
def get_video_ids(url): | |
''' | |
urlに含まれるYouTubeのvideo idを抽出する | |
''' | |
page = urllib2.urlopen(url) | |
soup = BeautifulSoup(page) | |
title = soup('title')[0].string | |
video_ids = [] | |
targets = [['embed', 'src', 'v\/([-\w]+)'], | |
['iframe', 'src', 'youtube.com\/embed\/([-\w]+)'], | |
['a', 'href', 'youtube.com\/watch\?v=([-\w]+)'], | |
['a', 'href', 'youtu\.be\/([-\w]+)']] | |
for tag, attr, exp in targets: | |
for element in soup(tag): | |
src = element.get(attr) | |
if src: | |
result = re.search(exp, src) | |
if result: | |
video_ids.append(result.group(1)) | |
tmp = [] | |
for video_id in video_ids: | |
if video_id not in tmp: | |
tmp.append(video_id) | |
return title, tmp | |
if __name__ == '__main__': | |
try: | |
# コマンドライン引数から取得先のURL | |
url = sys.argv[1] | |
except: | |
exit() | |
# urlのタイトルと含まれるビデオの取得 | |
title, video_ids = get_video_ids(url) | |
print len(video_ids) | |
# YouTubeクラスインスタンス | |
yt = YouTube(username, email, password, developer_key) | |
# プレイリストの作成 | |
playlist_uri = yt.AddPlaylist(title, title + " - " + url) | |
# 失敗 | |
failed = [] | |
# リトライ回数 | |
retry = 0 | |
# ビデオ番号 | |
n = 0 | |
# ビデオがあってリトライ回数が10を超えない限り継続 | |
while video_ids and retry < 10: | |
n += 1 | |
print n, | |
video_id = video_ids.pop(0) | |
try: | |
yt.AddVideoToPlaylist(playlist_uri, video_id) | |
time.sleep(1) | |
except gdata.service.RequestError as e: | |
print video_id | |
print type(e), e | |
# 短期間にアクセスしすぎないように... | |
if 'too_many_recent_calls' in str(e): | |
video_ids = [video_id] + video_ids | |
time.sleep(40) # 40秒待機 | |
retry += 1 | |
n -= 1 | |
except: | |
failed.append(video_id) | |
print video_id | |
print sys.exc_info() | |
# 残り | |
print 'rest: %s' % ','.join(video_ids) | |
# エラー | |
print 'failed: %s' % ','.join(failed) | |
# プレイリストURI | |
print playlist_uri |
...
- NAVERみたいに次のページがある場合に対応するか
- 人がまとめたものを使うってのはまずいのかな
- post-tube.satomacoto.comってどうやってつくったんだっけかな
- 連続再生だけが目的じゃなくてサイトごとにどんなビデオが貼り付けられているかとか自分の再生履歴やらお気に入りやらで何かしようとか思ってたんだっけ
- プレイリストの履歴は取れないからな…
No comments:
Post a Comment