Python獲取騰訊視頻真實地址

一声诸、需求

當我們?yōu)g覽視頻網頁時殊橙,有可能想要下載下來某個視頻衬衬,或者想要跳過臭長的廣告(慎),但是現(xiàn)在的網站往往不提供直接下載mp4或其他格式的視頻文件的功能刁笙。我們通過使用Python配合Chrome瀏覽器破花,可以獲取到騰訊視頻的視頻真實地址,直接下載視頻文件疲吸。

  • 為什么使用Python:很簡單座每,專注自己需要的事情,同樣的功能摘悴,使用其他語言峭梳,可能要自己寫http實現(xiàn),寫幾百行代碼烦租,但是用Python延赌,20多行代碼就可以了。

二叉橱、實現(xiàn)

以下以小豬佩奇某一集為例,看看如何得到視頻地址者蠕。
https://v.qq.com/x/cover/bzfkv5se8qaqel2/b0020buglwx.html
有一種思路是:使用Chrome瀏覽器的開發(fā)者工具窃祝,監(jiān)控網頁加載過程中發(fā)出的每個請求和服務器的回復,從中查找關于視頻信息的蛛絲馬跡踱侣。當發(fā)現(xiàn)可疑的request時粪小,查看該請求發(fā)出的所有參數(shù)內容,使用Python拼裝相應的參數(shù)抡句,并構造虛假的http請求頭探膊,模擬成用戶通過網頁的點擊,向服務器發(fā)出請求待榔,獲取服務器回復內容逞壁,然后從回復內容中解析出視頻地址流济。

根據(jù)以前的經驗,這些網站的開發(fā)者腌闯,在移動端的功能實現(xiàn)會相對簡單一些绳瘟,我們更容易識別和抓取,因此我們解析的時候使用瀏覽器模擬成移動端姿骏,如圖:

獲取視頻地址的關鍵請求

我們用Python糖声,拼接出圖中方框Request的URL地址,填入參數(shù)分瘦,發(fā)出GET請求蘸泻,就可以得到一個包含視頻信息的json字符串。
GET請求的URL是:

http://h5vv.video.qq.com/getinfo?

問號后面由很多包含參數(shù)名稱和值的組合構成嘲玫,例如otype=json&platform=11&defnpayver=1&appver=3.4.40
其中一個重要的參數(shù)vid悦施,就是視頻地址本身提供的:

vid參數(shù)

當我們發(fā)出get請求,得到的json數(shù)據(jù)類似這樣:

{
    "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-Vsr
eqSpl/",
                            "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地址趁冈,可以確定視頻地址的信息就在其中歼争,不過還需要分析一下,怎么樣根據(jù)這些數(shù)據(jù)把視頻地址拼接出來渗勘。
其實瀏覽器也是根據(jù)這個json數(shù)據(jù)沐绒,通過調用js腳本獲取到視頻地址,但是如果要通過解析js腳本獲取地址就會很麻煩旺坠,尤其是考慮到js腳本可能經過了壓縮和加密乔遮。所以還是通過瀏覽器開發(fā)者工具,查看瀏覽器實際get請求中的數(shù)據(jù)格式取刃,以供參考蹋肮。

視頻地址格式

經測試其中有些參數(shù)可以不傳入。最終代碼如下璧疗,只需傳入一個網址坯辩,就可以獲取到mp4格式視頻的一個url(默認就是最高清晰度)。

import requests
import re
import json

headers = {
    '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數(shù)據(jù)
    p = re.compile(r'({.*})', re.S)
    jsonstr = re.findall(p, html)[0]
    json_data = json.loads(jsonstr)
    print(jsonstr)

    # 解析json數(shù)據(jù)獲取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']  # 實際數(shù)據(jù)中有多個cdn可供選擇
    result = baseUrl + filename + '?vkey=' + fvkey
    return result

if __name__ == '__main__':
    url = input('請輸入騰訊視頻網址:')
    print('視頻下載地址:\n', getTencentVideoUrl(url))

三崩侠、問題:

  1. 實際上有些視頻是分成了多個小部分漆魔,這時就會需要獲取每個視頻的地址,下載下來然后再拼接成一個完整的視頻文件却音,如果想要做的話也是可以的改抡,自動下載多段視頻,然后自動合并成1個完整的文件系瓢。
    這里可能就不能只發(fā)送一次get請求了阿纤,而是根據(jù)視頻分割成了多少個,發(fā)送多次請求夷陋。
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末欠拾,一起剝皮案震驚了整個濱河市胰锌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌清蚀,老刑警劉巖匕荸,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異枷邪,居然都是意外死亡榛搔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門东揣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來践惑,“玉大人,你說我怎么就攤上這事嘶卧《酰” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵芥吟,是天一觀的道長侦铜。 經常有香客問我,道長钟鸵,這世上最難降的妖魔是什么钉稍? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮棺耍,結果婚禮上贡未,老公的妹妹穿的比我還像新娘。我一直安慰自己蒙袍,他們只是感情好俊卤,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著害幅,像睡著了一般消恍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上以现,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天哺哼,我揣著相機與錄音,去河邊找鬼叼风。 笑死,一個胖子當著我的面吹牛棍苹,可吹牛的內容都是我干的无宿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼枢里,長吁一口氣:“原來是場噩夢啊……” “哼孽鸡!你這毒婦竟也來了蹂午?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤彬碱,失蹤者是張志新(化名)和其女友劉穎豆胸,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巷疼,經...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡晚胡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了嚼沿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片估盘。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖骡尽,靈堂內的尸體忽然破棺而出遣妥,到底是詐尸還是另有隱情,我是刑警寧澤攀细,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布箫踩,位于F島的核電站,受9級特大地震影響谭贪,放射性物質發(fā)生泄漏境钟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一故河、第九天 我趴在偏房一處隱蔽的房頂上張望吱韭。 院中可真熱鬧,春花似錦鱼的、人聲如沸理盆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猿规。三九已至,卻和暖如春宙橱,著一層夾襖步出監(jiān)牢的瞬間姨俩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工师郑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留环葵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓宝冕,卻偏偏與公主長得像张遭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子地梨,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內容