]>
Raphaël G. Git Repositories - youtubedl/blob - youtube_dl/extractor/iqiyi.py
   2 from __future__ 
import unicode_literals
 
  10 from .common 
import InfoExtractor
 
  11 from ..compat 
import compat_urllib_parse
 
  12 from ..utils 
import ExtractorError
 
  15 class IqiyiIE(InfoExtractor
): 
  19     _VALID_URL 
= r
'http://(?:www\.)iqiyi.com/v_.+?\.html' 
  22         'url': 'http://www.iqiyi.com/v_19rrojlavg.html', 
  23         'md5': '2cb594dc2781e6c941a110d8f358118b', 
  25             'id': '9c1fb1b99d192b21c559e5a1a2cb3c73', 
  26             'title': '美国德州空中惊现奇异云团 酷似UFO', 
  30         'url': 'http://www.iqiyi.com/v_19rrhnnclk.html', 
  32             'id': 'e3f585b550a280af23c98b6cb2be19fb', 
  33             'title': '名侦探柯南第752集', 
  37                 'id': 'e3f585b550a280af23c98b6cb2be19fb_part1', 
  39                 'title': '名侦探柯南第752集', 
  43                 'id': 'e3f585b550a280af23c98b6cb2be19fb_part2', 
  45                 'title': '名侦探柯南第752集', 
  49                 'id': 'e3f585b550a280af23c98b6cb2be19fb_part3', 
  51                 'title': '名侦探柯南第752集', 
  55                 'id': 'e3f585b550a280af23c98b6cb2be19fb_part4', 
  57                 'title': '名侦探柯南第752集', 
  61                 'id': 'e3f585b550a280af23c98b6cb2be19fb_part5', 
  63                 'title': '名侦探柯南第752集', 
  67                 'id': 'e3f585b550a280af23c98b6cb2be19fb_part6', 
  69                 'title': '名侦探柯南第752集', 
  73                 'id': 'e3f585b550a280af23c98b6cb2be19fb_part7', 
  75                 'title': '名侦探柯南第752集', 
  79                 'id': 'e3f585b550a280af23c98b6cb2be19fb_part8', 
  81                 'title': '名侦探柯南第752集', 
  85             'skip_download': True, 
 100         return hashlib
.md5(text
.encode('utf-8')).hexdigest() 
 102     def construct_video_urls(self
, data
, video_id
, _uuid
): 
 111         def get_encode_code(l
): 
 116             for i 
in range(c 
- 1, -1, -1): 
 117                 a 
= do_xor(int(b
[c 
- i 
- 1], 16), i
) 
 121         def get_path_key(x
, format_id
, segment_index
): 
 122             mg 
= ')(*&^flash@#$%a' 
 123             tm 
= self
._download
_json
( 
 124                 'http://data.video.qiyi.com/t?tn=' + str(random
.random()), video_id
, 
 125                 note
='Download path key of segment %d for format %s' % (segment_index 
+ 1, format_id
) 
 127             t 
= str(int(math
.floor(int(tm
) / (600.0)))) 
 128             return self
.md5_text(t 
+ mg 
+ x
) 
 131         for format_item 
in data
['vp']['tkl'][0]['vs']: 
 132             if 0 < int(format_item
['bid']) <= 10: 
 133                 format_id 
= self
.get_format(format_item
['bid']) 
 139             video_urls_info 
= format_item
['fs'] 
 140             if not format_item
['fs'][0]['l'].startswith('/'): 
 141                 t 
= get_encode_code(format_item
['fs'][0]['l']) 
 142                 if t
.endswith('mp4'): 
 143                     video_urls_info 
= format_item
['flvs'] 
 145             for segment_index
, segment 
in enumerate(video_urls_info
): 
 147                 if not vl
.startswith('/'): 
 148                     vl 
= get_encode_code(vl
) 
 150                     vl
.split('/')[-1].split('.')[0], format_id
, segment_index
) 
 151                 filesize 
= segment
['b'] 
 152                 base_url 
= data
['vp']['du'].split('/') 
 153                 base_url
.insert(-1, key
) 
 154                 base_url 
= '/'.join(base_url
) 
 157                     'qyid': uuid
.uuid4().hex, 
 162                     'tn': str(int(time
.time())) 
 164                 api_video_url 
= base_url 
+ vl 
+ '?' + \
 
 165                     compat_urllib_parse
.urlencode(param
) 
 166                 js 
= self
._download
_json
( 
 167                     api_video_url
, video_id
, 
 168                     note
='Download video info of segment %d for format %s' % (segment_index 
+ 1, format_id
)) 
 171                     (video_url
, filesize
)) 
 173             video_urls_dict
[format_id
] = video_urls
 
 174         return video_urls_dict
 
 176     def get_format(self
, bid
): 
 177         matched_format_ids 
= [_format_id 
for _bid
, _format_id 
in self
._FORMATS
_MAP 
if _bid 
== str(bid
)] 
 178         return matched_format_ids
[0] if len(matched_format_ids
) else None 
 180     def get_bid(self
, format_id
): 
 181         matched_bids 
= [_bid 
for _bid
, _format_id 
in self
._FORMATS
_MAP 
if _format_id 
== format_id
] 
 182         return matched_bids
[0] if len(matched_bids
) else None 
 184     def get_raw_data(self
, tvid
, video_id
, enc_key
, _uuid
): 
 185         tm 
= str(int(time
.time())) 
 189             'src': self
.md5_text('youtube-dl'), 
 194             'enc': self
.md5_text(enc_key 
+ tail
), 
 196             'tn': random
.random(), 
 198             'authkey': self
.md5_text(self
.md5_text('') + tail
), 
 201         api_url 
= 'http://cache.video.qiyi.com/vms' + '?' + \
 
 202             compat_urllib_parse
.urlencode(param
) 
 203         raw_data 
= self
._download
_json
(api_url
, video_id
) 
 206     def get_enc_key(self
, swf_url
, video_id
): 
 207         # TODO: automatic key extraction 
 208         # last update at 2015-10-22 for Zombie::bite 
 209         # '7223c67061dbea1259d0ceb44f44b6d62288f4f80c972170de5201d2321060270e05'[2:66][0::2] 
 210         enc_key 
= '2c76de15dcb44bd28ff0927d50d31620' 
 213     def _real_extract(self
, url
): 
 214         webpage 
= self
._download
_webpage
( 
 215             url
, 'temp_id', note
='download video page') 
 216         tvid 
= self
._search
_regex
( 
 217             r
'data-player-tvid\s*=\s*[\'"](\d+)', webpage, 'tvid') 
 218         video_id = self._search_regex( 
 219             r'data-player-videoid\s*=\s*[\'"]([a
-f\d
]+)', webpage, 'video_id
') 
 220         swf_url = self._search_regex( 
 221             r'(http
://[^
\'"]+MainPlayer[^.]+\.swf)', webpage, 'swf player URL') 
 222         _uuid = uuid.uuid4().hex 
 224         enc_key = self.get_enc_key(swf_url, video_id) 
 226         raw_data = self.get_raw_data(tvid, video_id, enc_key, _uuid) 
 228         if raw_data['code'] != 'A000000': 
 229             raise ExtractorError('Unable to load data. Error code: ' + raw_data['code']) 
 231         if not raw_data['data']['vp']['tkl']: 
 232             raise ExtractorError('No support iQiqy VIP video') 
 234         data = raw_data['data'] 
 236         title = data['vi']['vn'] 
 238         # generate video_urls_dict 
 239         video_urls_dict = self.construct_video_urls( 
 240             data, video_id, _uuid) 
 244         for format_id in video_urls_dict: 
 245             video_urls = video_urls_dict[format_id] 
 246             for i, video_url_info in enumerate(video_urls): 
 247                 if len(entries) < i + 1: 
 248                     entries.append({'formats': []}) 
 249                 entries[i]['formats'].append( 
 251                         'url': video_url_info[0], 
 252                         'filesize': video_url_info[-1], 
 253                         'format_id': format_id, 
 254                         'preference': int(self.get_bid(format_id)) 
 258         for i in range(len(entries)): 
 259             self._sort_formats(entries[i]['formats']) 
 262                     'id': '%s_part%d' % (video_id, i + 1), 
 269                 '_type': 'multi_video', 
 276             info['id'] = video_id 
 277             info['title'] = title