X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=youtube_dl%2FInfoExtractors.py;h=d95423f7db63985742c44fb43869f668011c9fae;hb=55a1fa8a567540e38fbd9d8eb81ba98a7510203d;hp=81ab5487f3ece91c596d7dd07d817d53895b45d3;hpb=eeeb4daabc180e676323ca5b094a90e189efc53e;p=youtube-dl diff --git a/youtube_dl/InfoExtractors.py b/youtube_dl/InfoExtractors.py index 81ab5487f..d95423f7d 100644 --- a/youtube_dl/InfoExtractors.py +++ b/youtube_dl/InfoExtractors.py @@ -95,7 +95,7 @@ class InfoExtractor(object): class YoutubeIE(InfoExtractor): """Information extractor for youtube.com.""" - _VALID_URL = r'^((?:https?://)?(?:youtu\.be/|(?:\w+\.)?youtube(?:-nocookie)?\.com/)(?!view_play_list|my_playlists|artist|playlist)(?:(?:(?:v|embed|e)/)|(?:(?:watch(?:_popup)?(?:\.php)?)?(?:\?|#!?)(?:.+&)?v=))?)?([0-9A-Za-z_-]+)(?(1).+)?$' + _VALID_URL = r'^((?:https?://)?(?:youtu\.be/|(?:\w+\.)?youtube(?:-nocookie)?\.com/|tube.majestyc.net/)(?!view_play_list|my_playlists|artist|playlist)(?:(?:(?:v|embed|e)/)|(?:(?:watch(?:_popup)?(?:\.php)?)?(?:\?|#!?)(?:.+&)?v=))?)?([0-9A-Za-z_-]+)(?(1).+)?$' _LANG_URL = r'http://www.youtube.com/?hl=en&persist_hl=1&gl=US&persist_gl=1&opt_out_ackd=1' _LOGIN_URL = 'https://www.youtube.com/signup?next=/&gl=US&hl=en' _AGE_URL = 'http://www.youtube.com/verify_age?next_url=/&gl=US&hl=en' @@ -182,7 +182,7 @@ class YoutubeIE(InfoExtractor): end = "%02i:%02i:%02i,%03i" %(end/(60*60), end/60%60, end%60, end%1*1000) caption = unescapeHTML(caption) caption = unescapeHTML(caption) # double cycle, intentional - srt += str(n) + '\n' + srt += str(n+1) + '\n' srt += start + ' --> ' + end + '\n' srt += caption + '\n\n' return srt @@ -311,6 +311,11 @@ class YoutubeIE(InfoExtractor): self._downloader.trouble(u'ERROR: "token" parameter not in video info for unknown reason') return + # Check for "rental" videos + if 'ypc_video_rental_bar_text' in video_info and 'author' not in video_info: + self._downloader.trouble(u'ERROR: "rental" videos not supported') + return + # Start extracting information self.report_information_extraction(video_id) @@ -361,7 +366,8 @@ class YoutubeIE(InfoExtractor): srt_list = urllib2.urlopen(request).read() except (urllib2.URLError, httplib.HTTPException, socket.error), err: raise Trouble(u'WARNING: unable to download video subtitles: %s' % str(err)) - srt_lang_list = re.findall(r'lang_code="([\w\-]+)"', srt_list) + srt_lang_list = re.findall(r'name="([^"]*)"[^>]+lang_code="([\w\-]+)"', srt_list) + srt_lang_list = dict((l[1], l[0]) for l in srt_lang_list) if not srt_lang_list: raise Trouble(u'WARNING: video has no closed captions') if self._downloader.params.get('subtitleslang', False): @@ -369,14 +375,16 @@ class YoutubeIE(InfoExtractor): elif 'en' in srt_lang_list: srt_lang = 'en' else: - srt_lang = srt_lang_list[0] + srt_lang = srt_lang_list.keys()[0] if not srt_lang in srt_lang_list: raise Trouble(u'WARNING: no closed captions found in the specified language') - request = urllib2.Request('http://video.google.com/timedtext?hl=en&lang=%s&v=%s' % (srt_lang, video_id)) + request = urllib2.Request('http://www.youtube.com/api/timedtext?lang=%s&name=%s&v=%s' % (srt_lang, srt_lang_list[srt_lang], video_id)) try: srt_xml = urllib2.urlopen(request).read() except (urllib2.URLError, httplib.HTTPException, socket.error), err: raise Trouble(u'WARNING: unable to download video subtitles: %s' % str(err)) + if not srt_xml: + raise Trouble(u'WARNING: unable to download video subtitles') video_subtitles = self._closed_captions_xml_to_srt(srt_xml.decode('utf-8')) except Trouble as trouble: self._downloader.trouble(trouble[0]) @@ -1227,7 +1235,7 @@ class YoutubeSearchIE(InfoExtractor): InfoExtractor.__init__(self, downloader) def report_download_page(self, query, pagenum): - """Report attempt to download playlist page with given number.""" + """Report attempt to download search page with given number.""" query = query.decode(preferredencoding()) self._downloader.to_screen(u'[youtube] query "%s": Downloading page %s' % (query, pagenum)) @@ -1463,8 +1471,8 @@ class YoutubePlaylistIE(InfoExtractor): _VALID_URL = r'(?:https?://)?(?:\w+\.)?youtube\.com/(?:(?:course|view_play_list|my_playlists|artist|playlist)\?.*?(p|a|list)=|user/.*?/user/|p/|user/.*?#[pg]/c/)(?:PL)?([0-9A-Za-z-_]+)(?:/.*?/([0-9A-Za-z_-]+))?.*' _TEMPLATE_URL = 'http://www.youtube.com/%s?%s=%s&page=%s&gl=US&hl=en' - _VIDEO_INDICATOR_TEMPLATE = r'/watch\?v=(.+?)&list=PL%s&' - _MORE_PAGES_INDICATOR = r'(?m)>\s*Next\s*' + _VIDEO_INDICATOR_TEMPLATE = r'/watch\?v=(.+?)&list=(PL)?%s&' + _MORE_PAGES_INDICATOR = r'yt-uix-pager-next' IE_NAME = u'youtube:playlist' def __init__(self, downloader=None): @@ -1618,7 +1626,7 @@ class BlipTVUserIE(InfoExtractor): """Information Extractor for blip.tv users.""" _VALID_URL = r'(?:(?:(?:https?://)?(?:\w+\.)?blip\.tv/)|bliptvuser:)([^/]+)/*$' - _PAGE_SIZE = 10 + _PAGE_SIZE = 12 IE_NAME = u'blip.tv:user' def __init__(self, downloader=None): @@ -1638,31 +1646,31 @@ class BlipTVUserIE(InfoExtractor): username = mobj.group(1) - page_base = None + page_base = 'http://m.blip.tv/pr/show_get_full_episode_list?users_id=%s&lite=0&esi=1' request = urllib2.Request(url) try: page = urllib2.urlopen(request).read().decode('utf-8') - mobj = re.search(r'data-source-url="([^"]+)"', page) - page_base = "http://blip.tv" + unescapeHTML(mobj.group(1)) + mobj = re.search(r'data-users-id="([^"]+)"', page) + page_base = page_base % mobj.group(1) except (urllib2.URLError, httplib.HTTPException, socket.error), err: self._downloader.trouble(u'ERROR: unable to download webpage: %s' % str(err)) return - # Download video ids using BlipTV Page API. Result size per - # query is limited (currently to 10 videos) so we need to query + # Download video ids using BlipTV Ajax calls. Result size per + # query is limited (currently to 12 videos) so we need to query # page by page until there are no video ids - it means we got # all of them. video_ids = [] - pagenum = 0 + pagenum = 1 while True: self.report_download_page(username, pagenum) - request = urllib2.Request( page_base + "&page=" + str(pagenum+1) ) + request = urllib2.Request( page_base + "&page=" + str(pagenum) ) try: page = urllib2.urlopen(request).read().decode('utf-8') @@ -2004,7 +2012,7 @@ class BlipTVIE(InfoExtractor): else: cchar = '?' json_url = url + cchar + 'skin=json&version=2&no_wrap=1' - request = urllib2.Request(json_url) + request = urllib2.Request(json_url.encode('utf-8')) self.report_extraction(mobj.group(1)) info = None try: @@ -2062,6 +2070,7 @@ class BlipTVIE(InfoExtractor): self._downloader.trouble(u'ERROR: unable to parse video information: %s' % repr(err)) return + std_headers['User-Agent'] = 'iTunes/10.6.1' return [info] @@ -2280,12 +2289,14 @@ class EscapistIE(InfoExtractor): self.report_extraction(showName) try: - webPageBytes = urllib2.urlopen(url).read() + webPage = urllib2.urlopen(url) + webPageBytes = webPage.read() + m = re.match(r'text/html; charset="?([^"]+)"?', webPage.headers['Content-Type']) + webPage = webPageBytes.decode(m.group(1) if m else 'utf-8') except (urllib2.URLError, httplib.HTTPException, socket.error), err: self._downloader.trouble(u'ERROR: unable to download webpage: ' + unicode(err)) return - webPage = webPageBytes.decode('utf-8') descMatch = re.search('