Python获取腾讯视频真实地址

Python获取腾讯视频真实地址

一、需求当我们浏览视频网页时,有可能想要下载下来某个视频,或者想要 跳过臭长的广告(慎),但是现在的网站往往不提供直接下载mp4或其他格式的视频文件的功能。我们通过使用Python配合Chrome浏览器,可以获取到腾讯视频的视频真实地址,直接下载视频文件。

二、实现以下以小猪佩奇某一集为例,看看如何得到视频地址。

1https://v.qq.com/x/cover/bzfkv5se8qaqel2/b0020buglwx.html有一种思路是:使用Chrome浏览器的开发者工具,监控网页加载过程中发出的每个请求和服务器的回复,从中查找关于视频信息的蛛丝马迹。当发现可疑的request时,查看该请求发出的所有参数内容,使用Python拼装相应的参数,并构造虚假的http请求头,模拟成用户通过网页的点击,向服务器发出请求,获取服务器回复内容,然后从回复内容中解析出视频地址。

根据以前的经验,这些网站的开发者,在移动端的功能实现会相对简单一些,我们更容易识别和抓取,因此我们解析的时候使用浏览器模拟成移动端,如图:

我们用Python,拼接出图中方框Request的URL地址,填入参数,发出GET请求,就可以得到一个包含视频信息的json字符串。GET请求的URL是:

1http://h5vv.video.qq.com/getinfo?问号后面由很多包含参数名称和值的组合构成,例如

otype=json&platform=11&defnpayver=1&appver=3.4.40

其中一个重要的参数vid,就是视频地址本身提供的:

当我们发出get请求,得到的json数据类似这样:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220{ "dltype": 1, "exem": 0, "fl": { "cnt": 4, "fi": [ { "id": 10203, "name": "sd", "lmt": 0, "sb": 1, "cname": "标清;(270P)", "br": 37, "profile": 1, "drm": 0, "video": 1, "audio": 1, "fs": 5705248, "super": 0, "hdr10enh": 0, "sname": "标清", "resolution": "270P", "sl": 0 }, { "id": 10212, "name": "hd", "lmt": 0, "sb": 1, "cname": "高清;(480P)", "br": 42, "profile": 1, "drm": 0, "video": 1, "audio": 1, "fs": 10092707, "super": 0, "hdr10enh": 0, "sname": "高清", "resolution": "480P", "sl": 0 }, { "id": 10201, "name": "shd", "lmt": 0, "sb": 1, "cname": "超清;(720P)", "br": 62, "profile": 1, "drm": 0, "video": 1, "audio": 1, "fs": 19246460, "super": 0, "hdr10enh": 0, "sname": "超清", "resolution": "720P", "sl": 1 }, { "id": 10209, "name": "fhd", "lmt": 3, "sb": 1, "cname": "蓝光;(1080P)", "br": 67, "profile": 1, "drm": 0, "video": 1, "audio": 1, "fs": 40730393, "super": 0, "hdr10enh": 0, "sname": "蓝光", "resolution": "1080P", "sl": 0 } ] }, "fp2p": 2, "hs": 0, "ip": "113.110.230.111", "ls": 0, "preview": 299, "s": "o", "sfl": { "cnt": 0 }, "tstid": 3, "tm": 1574871391, "vl": { "cnt": 1, "vi": [ { "br": 62, "ch": 0, "cl": { "fc": 1, "ci": [ { "idx": 1, "cs": 19246460, "cd": "299.96", "cmd5": "f579ecf14d0aa58c0bc846f40ebe0c7c", "vkey": "", "urllist": [], "keyid": "q0020tfo8j7.10201.1" } ] }, "ct": 21600, "drm": 0, "dsb": 0, "fclip": 1, "fmd5": "f579ecf14d0aa58c0bc846f40ebe0c7c", "fn": "q0020tfo8j7.p201.mp4", "fs": 19246460, "fst": 5, "fvkey": "6D7FDA1832CC88940F6F20E281EE9727639DF6B0D70FFF73083818AB45289A0507A0FD280B370536D0918C1A3564AA34F9698B83C61A88962F765BBF7EA67010F5B4D1D11737658D783A86ED5A5EA22933C2838506DEC3B16C1223E7727442E18A1AA2630567BFD436C4353F31F5A0E5", "head": 0, "hevc": 0, "iflag": 0, "level": 0, "lnk": "q0020tfo8j7", "logo": 1, "mst": 8, "pl": [ { "cnt": 3, "pd": [ { "cd": 2, "h": 45, "w": 80, "r": 10, "c": 10, "fmt": 40001, "fn": "q1", "url": "http: //puui.qpic.cn/video_caps/0/" }, { "cd": 2, "h": 90, "w": 160, "r": 5, "c": 5, "fmt": 40002, "fn": "q2", "url": "http://puui.qpic.cn/video_caps/0/" }, { "cd": 2, "h": 135, "w": 240, "r": 5, "c": 5, "fmt": 40003, "fn": "q3", "url": "http://puui.qpic.cn/video_caps/0/" } ] } ], "share": 1, "sp": 0, "st": 2, "tail": 0, "td": "299.96", "ti": "恐龙先生弄丢了", "tie": 0, "type": 1036, "ul": { "ui": [ { "url":"http://113.105.141.22/vlive.qqvideo.tc.qq.com/AF094anUFAellJsZIYnUozoSnZLLcgP480IDBq7WleyE/uwMROfz2r5zCIaQXGdGnC2dfKb2-hlZWyQT_tzD-VsreqSpl/", "vt": 203, "dtc": 0, "dt": 2 }, { "url": "http: //lmsjy.qq.com/uwMROfz2r5zCIaQXGdGnCmdfKb0i2sHXl3M2Wy9RmDZEeplY/", "vt": 170, "dtc": 0, "dt": 2 }, { "url": "http://lmbsy.qq.com/uwMROfz2r5zCIaQXGdGmm2dfKb0Pk2-yYlV7ZrIrO9TJ-LqW/", "vt": 130, "dtc": 0, "dt": 2 }, { "url": "http://video.dispatch.tc.qq.com/uwMROfz2r5zCIaQXGdGmlWdfKb2svKK_VNuAbg616jtBjIn0/", "vt": 0, "dtc": 0, "dt": 2 } ] }, "vh": 720, "vid": "b0020buglwx", "videotype": 106, "vr": 0, "vst": 2, "vw": 1280, "wh": 1.7777778, "wl": { "wi": [] }, "uptime": 1465198419, "fvideo": 0, "cached": 1, "fvpint": 0, "swhdcp": 0 } ] }}看到这其中包含很多的url地址,可以确定视频地址的信息就在其中,不过还需要分析一下,怎么样根据这些数据把视频地址拼接出来。其实浏览器也是根据这个json数据,通过调用js脚本获取到视频地址,但是如果要通过解析js脚本获取地址就会很麻烦,尤其是考虑到js脚本可能经过了压缩和加密。所以还是通过浏览器开发者工具,查看浏览器实际get请求中的数据格式,以供参考。

经测试其中有些参数可以不传入。最终代码如下,只需传入一个网址,就可以获取到mp4格式视频的一个url(默认就是最高清晰度)。

1234567891011121314151617181920212223242526272829import requestsimport reimport jsonheaders = { 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}def getTencentVideoUrl(url): vid = url.split('/')[-1][:-5] url = 'http://h5vv.video.qq.com/getinfo?otype=json&platform=11&defnpayver=1&appver=3.4.40&defn=fhd&vid=' + vid html = requests.get(url, headers=headers).text # 获取json数据 p = re.compile(r'({.*})', re.S) jsonstr = re.findall(p, html)[0] json_data = json.loads(jsonstr) print(jsonstr) # 解析json数据获取url fvkey = json_data['vl']['vi'][0]['fvkey'] keyid = json_data['vl']['vi'][0]['cl']['ci'][0]['keyid'].split('.') filename = keyid[0] + '.p' + keyid[1][2:] + '.' + keyid[2] + '.mp4' baseUrl = json_data['vl']['vi'][0]['ul']['ui'][3]['url'] # 实际数据中有多个cdn可供选择 result = baseUrl + filename + '?vkey=' + fvkey return resultif __name__ == '__main__': url = input('请输入腾讯视频网址:') print('视频下载地址:\n', getTencentVideoUrl(url))三、问题:实际上有些视频是分成了多个小部分,这时就会需要获取每个视频的地址,下载下来然后再拼接成一个完整的视频文件,如果想要做的话也是可以的,自动下载多段视频,然后自动合并成1个完整的文件。这里可能就不能只发送一次get请求了,而是根据视频分割成了多少个,发送多次请求。

相关推荐