From 7c4f048940b4c96735fae217d3ca82b53bb40ff1 Mon Sep 17 00:00:00 2001 From: wiggles Date: Tue, 15 Sep 2015 01:06:17 -0700 Subject: [PATCH 1/2] [fivethirtyeight] Add new extractor --- youtube_dl/extractor/__init__.py | 1 + youtube_dl/extractor/fivethirtyeight.py | 52 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 youtube_dl/extractor/fivethirtyeight.py diff --git a/youtube_dl/extractor/__init__.py b/youtube_dl/extractor/__init__.py index 74b7df463..aebd6029a 100644 --- a/youtube_dl/extractor/__init__.py +++ b/youtube_dl/extractor/__init__.py @@ -169,6 +169,7 @@ from .fc2 import FC2IE from .firstpost import FirstpostIE from .firsttv import FirstTVIE from .fivemin import FiveMinIE +from .fivethirtyeight import FivethirtyeightIE from .fivetv import FiveTVIE from .fktv import ( FKTVIE, diff --git a/youtube_dl/extractor/fivethirtyeight.py b/youtube_dl/extractor/fivethirtyeight.py new file mode 100644 index 000000000..574974292 --- /dev/null +++ b/youtube_dl/extractor/fivethirtyeight.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + +from __future__ import unicode_literals +from .common import InfoExtractor +from youtube_dl.compat import compat_urllib_request +from youtube_dl import utils + + +class FivethirtyeightIE(InfoExtractor): + _VALID_URL = r'http://fivethirtyeight\.com/.+' + _TEST = { + 'url': 'http://fivethirtyeight.com/features/rage-against-the-machines/', + 'md5': 'c825a057981316c4d4444fefea35a108', + 'info_dict': { + 'id': '11694550', + 'ext': 'mp4', + 'title': 'Rage Against The Machines', + 'description': 'This is an excerpted chapter from “The Signal and the Noise: Why So Many Predictions Fail — but Some Don’t” by Nate Silver, editor in chief of FiveThirtyEight. …', + 'duration': 1037, + } + } + + def _real_extract(self, url): + webpage = self._download_webpage(url, 'video_id') + video_id = self._html_search_regex(r'.*data-video-id=\'(.*)\' data-cms.*', webpage, 'video_id') + title = self._html_search_regex(r'(.*)\s*\|', webpage, 'title') + + data = self._download_json( + 'http://espn.go.com/videohub/video/util/getMinifiedClipJsonById?id=%s&cms=espn&device=mobile&omniReportSuite=wdgespvideo,wdgespfivethirtyeight,wdgespge&xhr=1' % video_id, video_id) + + url = data["videos"][0]["links"]["mobile"]["href"] + + request = compat_urllib_request.Request(url) + request.add_header('User-Agent', 'ipad') + + formats = self._extract_m3u8_formats(request, 'display_id', 'mp4') + + formats[0]["url"] = request.get_full_url() + + for idx, val in enumerate(formats): + formats[idx]["url"] = formats[idx]["url"].replace('adsegmentlength=5', 'adsegmentlength=0') + + self._sort_formats(formats) + + return { + 'id': video_id, + 'title': title, + 'formats': formats, + 'description': self._html_search_meta('description', webpage, default=None), + 'thumbnail': data["videos"][0]["posterImages"]["full"]["href"], + 'duration': utils.parse_duration(self._search_regex('mediaLength=(\d\d%3A\d\d%3A\d\d)&', data["videos"][0]["links"]["mobile"]["omniHref"], 'duration').replace('%3A', ':')), + } From 0b3bf203939b74cf086edfb7a495203e7a2a6903 Mon Sep 17 00:00:00 2001 From: bikeseat <bikeseat@gmail.com> Date: Tue, 15 Sep 2015 12:43:14 -0700 Subject: [PATCH 2/2] made changes to fivethirtyeight extractor from PR --- youtube_dl/extractor/fivethirtyeight.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/youtube_dl/extractor/fivethirtyeight.py b/youtube_dl/extractor/fivethirtyeight.py index 574974292..06fb79286 100644 --- a/youtube_dl/extractor/fivethirtyeight.py +++ b/youtube_dl/extractor/fivethirtyeight.py @@ -7,7 +7,7 @@ from youtube_dl import utils class FivethirtyeightIE(InfoExtractor): - _VALID_URL = r'http://fivethirtyeight\.com/.+' + _VALID_URL = r'https?://fivethirtyeight\.com/.+/(?P<id>.+?)/' _TEST = { 'url': 'http://fivethirtyeight.com/features/rage-against-the-machines/', 'md5': 'c825a057981316c4d4444fefea35a108', @@ -21,19 +21,20 @@ class FivethirtyeightIE(InfoExtractor): } def _real_extract(self, url): - webpage = self._download_webpage(url, 'video_id') - video_id = self._html_search_regex(r'.*data-video-id=\'(.*)\' data-cms.*', webpage, 'video_id') - title = self._html_search_regex(r'<title>(.*)\s*\|', webpage, 'title') + display_id = self._match_id(url) + webpage = self._download_webpage(url, display_id) + video_id = self._html_search_regex(r'data-video-id=\'(.+?)\' data-cms', webpage, display_id) + title = self._html_search_regex(r'<title>(.+?)\s*\|', webpage, 'title') data = self._download_json( - 'http://espn.go.com/videohub/video/util/getMinifiedClipJsonById?id=%s&cms=espn&device=mobile&omniReportSuite=wdgespvideo,wdgespfivethirtyeight,wdgespge&xhr=1' % video_id, video_id) + 'http://espn.go.com/videohub/video/util/getMinifiedClipJsonById?id=%s&cms=espn&device=mobile&omniReportSuite=wdgespvideo,wdgespfivethirtyeight,wdgespge&xhr=1' % video_id, display_id) url = data["videos"][0]["links"]["mobile"]["href"] request = compat_urllib_request.Request(url) request.add_header('User-Agent', 'ipad') - formats = self._extract_m3u8_formats(request, 'display_id', 'mp4') + formats = self._extract_m3u8_formats(request, display_id, 'mp4') formats[0]["url"] = request.get_full_url()