11#!/usr/bin/env python
22
3+ import re
4+ import json
5+
6+ from lulu .util import log
7+ from lulu .extractors .qie import download as qieDownload
8+ from lulu .extractors .qie_video import download_by_url as qie_video_download
9+ from lulu .common import (
10+ match1 ,
11+ matchall ,
12+ url_info ,
13+ print_info ,
14+ get_content ,
15+ url_locations ,
16+ download_urls ,
17+ playlist_not_supported ,
18+ )
19+
20+
321__all__ = ['qq_download' ]
22+ site_info = 'QQ.com'
423
5- from ..common import *
6- from ..util .log import *
7- from .qie import download as qieDownload
8- from .qie_video import download_by_url as qie_video_download
9- from urllib .parse import urlparse ,parse_qs
1024
11- def qq_download_by_vid (vid , title , output_dir = '.' , merge = True , info_only = False ):
12- info_api = 'http://vv.video.qq.com/getinfo?otype=json&appver=3.2.19.333&platform=11&defnpayver=1&vid={}' .format (vid )
25+ def qq_download_by_vid (
26+ vid , title , output_dir = '.' , merge = True , info_only = False
27+ ):
28+ info_api = (
29+ 'http://vv.video.qq.com/getinfo?otype=json&appver=3.2.19.333'
30+ '&platform=11&defnpayver=1&vid={}' .format (vid )
31+ )
1332 info = get_content (info_api )
1433 video_json = json .loads (match1 (info , r'QZOutputJson=(.*)' )[:- 1 ])
15-
1634 fn_pre = video_json ['vl' ]['vi' ][0 ]['lnk' ]
1735 title = video_json ['vl' ]['vi' ][0 ]['ti' ]
1836 host = video_json ['vl' ]['vi' ][0 ]['ul' ]['ui' ][0 ]['url' ]
@@ -21,23 +39,30 @@ def qq_download_by_vid(vid, title, output_dir='.', merge=True, info_only=False):
2139 if seg_cnt == 0 :
2240 seg_cnt = 1
2341
24- best_quality = streams [- 1 ]['name' ]
42+ # best_quality = streams[-1]['name']
2543 part_format_id = streams [- 1 ]['id' ]
2644
27- part_urls = []
45+ part_urls = []
2846 total_size = 0
2947 for part in range (1 , seg_cnt + 1 ):
30- #if seg_cnt == 1 and video_json['vl']['vi'][0]['vh'] <= 480:
31- # filename = fn_pre + '.mp4'
32- #else:
33- # filename = fn_pre + '.p' + str(part_format_id % 10000) + '.' + str(part) + '.mp4'
34- filename = fn_pre + '.p' + str (part_format_id % 10000 ) + '.' + str (part ) + '.mp4'
35- key_api = "http://vv.video.qq.com/getkey?otype=json&platform=11&format={}&vid={}&filename={}&appver=3.2.19.333" .format (part_format_id , vid , filename )
48+ filename = '{}.p{}.{}.mp4' .format (
49+ fn_pre , str (part_format_id % 10000 ), str (part )
50+ )
51+ key_api = (
52+ 'http://vv.video.qq.com/getkey?otype=json&platform=11&'
53+ 'format={}&vid={}&filename={}&appver=3.2.19.333' .format (
54+ part_format_id , vid , filename
55+ )
56+ )
3657 part_info = get_content (key_api )
3758 key_json = json .loads (match1 (part_info , r'QZOutputJson=(.*)' )[:- 1 ])
3859 if key_json .get ('key' ) is None :
3960 vkey = video_json ['vl' ]['vi' ][0 ]['fvkey' ]
40- url = '{}{}?vkey={}' .format (video_json ['vl' ]['vi' ][0 ]['ul' ]['ui' ][0 ]['url' ], fn_pre + '.mp4' , vkey )
61+ url = '{}{}?vkey={}' .format (
62+ video_json ['vl' ]['vi' ][0 ]['ul' ]['ui' ][0 ]['url' ],
63+ fn_pre + '.mp4' ,
64+ vkey
65+ )
4166 else :
4267 vkey = key_json ['key' ]
4368 url = '{}{}?vkey={}' .format (host , filename , vkey )
@@ -54,11 +79,20 @@ def qq_download_by_vid(vid, title, output_dir='.', merge=True, info_only=False):
5479
5580 print_info (site_info , title , ext , total_size )
5681 if not info_only :
57- download_urls (part_urls , title , ext , total_size , output_dir = output_dir , merge = merge )
82+ download_urls (
83+ part_urls , title , ext , total_size , output_dir = output_dir ,
84+ merge = merge
85+ )
5886
59- def kg_qq_download_by_shareid (shareid , output_dir = '.' , info_only = False , caption = False ):
87+
88+ def kg_qq_download_by_shareid (
89+ shareid , output_dir = '.' , info_only = False , caption = False
90+ ):
6091 BASE_URL = 'http://cgi.kg.qq.com/fcgi-bin/kg_ugc_getdetail'
61- params_str = '?dataType=jsonp&jsonp=callback&jsonpCallback=jsopgetsonginfo&v=4&outCharset=utf-8&shareid=' + shareid
92+ params_str = (
93+ '?dataType=jsonp&jsonp=callback&jsonpCallback=jsopgetsonginfo&'
94+ 'v=4&outCharset=utf-8&shareid={}' .format (shareid )
95+ )
6296 url = BASE_URL + params_str
6397 content = get_content (url )
6498 json_str = content [len ('jsonpcallback(' ):- 1 ]
@@ -70,7 +104,10 @@ def kg_qq_download_by_shareid(shareid, output_dir='.', info_only=False, caption=
70104 real_url = real_url .replace ('\/' , '/' )
71105
72106 ksong_mid = json_data ['data' ]['ksong_mid' ]
73- lyric_url = 'http://cgi.kg.qq.com/fcgi-bin/fcg_lyric?jsonpCallback=jsopgetlrcdata&outCharset=utf-8&ksongmid=' + ksong_mid
107+ lyric_url = (
108+ 'http://cgi.kg.qq.com/fcgi-bin/fcg_lyric?jsonpCallback=jsopgetlrcdata&'
109+ 'outCharset=utf-8&ksongmid={}' .format (ksong_mid )
110+ )
74111 lyric_data = get_content (lyric_url )
75112 lyric_string = lyric_data [len ('jsopgetlrcdata(' ):- 1 ]
76113 lyric_json = json .loads (lyric_string )
@@ -94,24 +131,35 @@ def kg_qq_download_by_shareid(shareid, output_dir='.', info_only=False, caption=
94131 f .write (line )
95132 f .write ('\n ' )
96133
134+
97135def qq_download (url , output_dir = '.' , merge = True , info_only = False , ** kwargs ):
98- """"""
99136 if re .match (r'https?://egame.qq.com/live\?anchorid=(\d+)' , url ):
100137 from . import qq_egame
101- qq_egame .qq_egame_download (url , output_dir = output_dir , merge = merge , info_only = info_only , ** kwargs )
138+ qq_egame .qq_egame_download (
139+ url , output_dir = output_dir , merge = merge , info_only = info_only ,
140+ ** kwargs
141+ )
102142 return
103143
104144 if 'kg.qq.com' in url or 'kg2.qq.com' in url :
105145 shareid = url .split ('?s=' )[- 1 ]
106146 caption = kwargs ['caption' ]
107- kg_qq_download_by_shareid (shareid , output_dir = output_dir , info_only = info_only , caption = caption )
147+ kg_qq_download_by_shareid (
148+ shareid , output_dir = output_dir , info_only = info_only ,
149+ caption = caption
150+ )
108151 return
109152
110153 if 'live.qq.com' in url :
111154 if 'live.qq.com/video/v' in url :
112- qie_video_download (url , output_dir = output_dir , merge = merge , info_only = info_only , ** kwargs )
155+ qie_video_download (
156+ url , output_dir = output_dir , merge = merge , info_only = info_only ,
157+ ** kwargs
158+ )
113159 else :
114- qieDownload (url , output_dir = output_dir , merge = merge , info_only = info_only )
160+ qieDownload (
161+ url , output_dir = output_dir , merge = merge , info_only = info_only
162+ )
115163 return
116164
117165 if 'mp.weixin.qq.com/s?' in url :
@@ -121,19 +169,21 @@ def qq_download(url, output_dir='.', merge=True, info_only=False, **kwargs):
121169 qq_download_by_vid (vid , vid , output_dir , merge , info_only )
122170 return
123171
124- #do redirect
172+ # do redirect
125173 if 'v.qq.com/page' in url :
126174 # for URLs like this:
127175 # http://v.qq.com/page/k/9/7/k0194pwgw97.html
128176 new_url = url_locations ([url ])[0 ]
129177 if url == new_url :
130- #redirect in js?
178+ # redirect in js?
131179 content = get_content (url )
132- url = match1 (content ,r'window\.location\.href="(.*?)"' )
180+ url = match1 (content , r'window\.location\.href="(.*?)"' )
133181 else :
134182 url = new_url
135183
136- if 'kuaibao.qq.com' in url or re .match (r'http://daxue.qq.com/content/content/id/\d+' , url ):
184+ if 'kuaibao.qq.com' in url or re .match (
185+ r'http://daxue.qq.com/content/content/id/\d+' , url
186+ ):
137187 content = get_content (url )
138188 vid = match1 (content , r'vid\s*=\s*"\s*([^"]+)"' )
139189 title = match1 (content , r'title">([^"]+)</p>' )
@@ -144,22 +194,34 @@ def qq_download(url, output_dir='.', merge=True, info_only=False, **kwargs):
144194 title = vid
145195 else :
146196 content = get_content (url )
147- #vid = parse_qs(urlparse(url).query).get('vid') #for links specified vid like http://v.qq.com/cover/p/ps6mnfqyrfo7es3.html?vid=q0181hpdvo5
148- rurl = match1 (content , r'<link.*?rel\s*=\s*"canonical".*?href\s*="(.+?)".*?>' ) #https://v.qq.com/x/cover/9hpjiv5fhiyn86u/t0522x58xma.html
149- vid = ""
197+ # vid = parse_qs(urlparse(url).query).get('vid')
198+ # for links specified vid like
199+ # http://v.qq.com/cover/p/ps6mnfqyrfo7es3.html?vid=q0181hpdvo5
200+ rurl = match1 (
201+ content , r'<link.*?rel\s*=\s*"canonical".*?href\s*="(.+?)".*?>'
202+ ) # https://v.qq.com/x/cover/9hpjiv5fhiyn86u/t0522x58xma.html
203+ vid = ''
150204 if rurl :
151205 vid = rurl .split ('/' )[- 1 ].split ('.' )[0 ]
152- vid = vid if vid else url .split ('/' )[- 1 ].split ('.' )[0 ] #https://v.qq.com/x/cover/ps6mnfqyrfo7es3/q0181hpdvo5.html?
153- vid = vid if vid else match1 (content , r'vid"*\s*:\s*"\s*([^"]+)"' ) #general fallback
206+ if vid == 'undefined' :
207+ vid = ''
208+ # https://v.qq.com/x/cover/ps6mnfqyrfo7es3/q0181hpdvo5.html?
209+ vid = vid if vid else url .split ('/' )[- 1 ].split ('.' )[0 ]
210+ # general fallback
211+ vid = vid if vid else match1 (content , r'vid"*\s*:\s*"\s*([^"]+)"' )
154212 if not vid :
155213 vid = match1 (content , r'id"*\s*:\s*"(.+?)"' )
156- title = match1 (content ,r'<a.*?id\s*=\s*"%s".*?title\s*=\s*"(.+?)".*?>' % vid )
214+ title = match1 (
215+ content , r'<a.*?id\s*=\s*"{}".*?title\s*=\s*"(.+?)".*?>' .format (
216+ vid
217+ )
218+ )
157219 title = match1 (content , r'title">([^"]+)</p>' ) if not title else title
158220 title = match1 (content , r'"title":"([^"]+)"' ) if not title else title
159- title = vid if not title else title # general fallback
221+ title = vid if not title else title # general fallback
160222
161223 qq_download_by_vid (vid , title , output_dir , merge , info_only )
162224
163- site_info = "QQ.com"
225+
164226download = qq_download
165- download_playlist = playlist_not_supported ('qq' )
227+ download_playlist = playlist_not_supported (site_info )
0 commit comments