Python爬取視頻指南

前言

前兩天爾羽說讓我爬一下菜鳥窩的教程視頻,這次就跟大家來說說Python爬取視頻的經驗

正文

https://www.cniao5.com/

菜鳥窩上有很多教程視頻,但是這些視頻好像沒有直接的下載地址,而且有些教程視頻還是有期限的,那麼問題就產生了
我看的速度比較慢而且視頻又很多,沒等我看完視頻就到期了怎麼辦?這時候寫一個爬蟲將這些教程視頻下載下來就很好地解決了這個問題

當然,對於某些視頻網站的VIP電影、視頻之類的,一般情況下是無法在沒有開通VIP的情況下用爬蟲下載的,因爲涉及到利益問題,同時數據傳輸也是加密的;想要看的話還是得開通會員再進行爬取

回到這次的目標上來,我們要爬取的是

https://www.cniao5.com/course/lessons/10153

上面的24章,共計202個教程視頻


接下來我們來看看我們應該如何獲取這些視頻
首先我們看一下這個界面的源代碼中沒有關於課程視頻的信息,那麼我們點進去一個視頻看看

通過開發者工具我們可以看到左側都是這次加載視頻是動態加載的信息,我們一個個來看
首先是url,我們可以看到這個鏈接是 Post 方式請求的(然鵝實際上再通過postman測試可以知道,並不用帶上什麼參數請求,嚇唬人呢...)



這就是url返回的數據,其中 hd 、shd 代表高清、超清的視頻類型,而當你訪問這個鏈接後會自動下載一個 m3u8 文件,這介紹一下

m3u8 文件是指UTF-8編碼格式的M3U文件。M3U文件是記錄了一個索引純文本文件,打開它時播放軟件並不是播放它,而是根據它的索引找到對應的音視頻文件的網絡地址進行在線播放

而我們下載視頻的方式就是通過向m3u8文件中的這些 .ts 的鏈接發送請求而下載一個個 ts視頻流 (暫時這麼稱呼)

下一個就是 chapters ,這裏呢則是包含了所有24章視頻的一些基本信息

注意這裏的 vid 參數,之後我們會用到


這個就是網頁上加載的m3u8 文件


這看似亂碼的ts文件下載下來後就是一個幾秒鐘的視頻了


而我們最後要做的就是將這些 ts 文件合成爲一個 mp4 文件

那麼如何來操作呢?

思路

通過請求 chapters 的鏈接獲取每一個章節中每一個lesson的播放 url 地址(就是返回中帶有 hd 、shd的),取出並請求 hd 的鏈接,下載m3u8文件,匹配m3u8文件中的每一個 ts ,請求 ts 文件對應的鏈接並下載到本地,最後合成爲一個mp4視頻

來跟着代碼看一下
首先小編是在本地先用代碼創建好最終合成視頻的存放的空文件夾以便訪問


def mkd():
    for i in range(1, 25):
        finalpath = 'D:\\Python\\PycharmProject\\FinalCniao5\\{}'.format(i)
        # 判斷路徑文件是否存在,不存在則創建
        f = os.path.exists(finalpath)
        if not f:
            os.makedirs(finalpath)
            print('make file success...')
        else:
            print('file already exists...')

接着創建對應章節的文件夾

# 防止 requests 開得太多
s = requests.session()
r_chapters = s.get('https://www.cniao5.com/api/v1/course/10153/chapters')
json_chapters = r_chapters.json()
# print(json_chapters)
for chapter in json_chapters:
    # 每一個章節
    chapter_name = chapter['bsort']
    print(chapter_name)
    # 根據課程數創建對應的課程文件夾
    path1 = self.file_path1.format(chapter_name)  
    f = os.path.exists(path1)
    if not f:
        os.makedirs(path1)
        print('make file success...')
    else:
        print('file already exists...')

對章節中的每一個課程,獲取其 id、key、file_id 創建對應的課程文件夾(用來保存ts文件)

for lessons in chapter['lessons']:
    # 章節下的每一個課程
    lessons_name = 'lessons' + str(lessons['bsort'])
    # 獲取其id
    video_id = lessons['video_info']['vid']
    # 獲取 key
    key = lessons['key']
    # 後面用到
    file_id = lessons['video_info']['file_id']
    print(lessons_name, video_id)
    # 每個視頻創建一個視頻id的文件夾
    path = 'D:\\Python\\PycharmProject\\Cniao5\\{}\\{}'.format(chapter_name, lessons_name)
    f = os.path.exists(path)
    # 基於中斷後,創建文件時判斷,若存在該文件夾則跳過對該視頻的下載,若不存在則繼續

對於之後則需要分爲兩種情況,我不知道菜鳥窩是怎麼想的,你可以看到對於有的視頻 vid 有具體的數值,有的則是 0


也就是說對於 vid 有值的我們可以很容易構造 url 鏈接從而獲取 m3u8 文件進而下載 ts 視頻;但是對於沒有的來說就麻煩了,我們不能直接構造這個 url 鏈接
而對於這一類視頻則是這樣的


這類視頻不是通過 m3u8 來處理視頻的而是直接給了一個 mp4 的地址,那麼也就是說對於 vid 爲0的視頻我們需要訪問

https://playvideo.qcloud.com/getplayinfo/v2/1255567694/5285890782726972640

纔可以拿到這個視頻,那麼這個 url 中後面的兩個參數是什麼呢
這個 5285890782726972640 我們在上圖中可以發現就是之前提到的 file_id 這也是我們爲什麼要獲取的原因;而前面的1255567694你多看幾個就知道這個是不變的

而當你去訪問這個 MP4 的鏈接時菜鳥窩會告訴你,你沒有權限請求這個鏈接,what?
而這時候你要知道所謂爬蟲就是模擬人對瀏覽器進行的操作而獲取一定的結果,那麼我們可以帶上請求頭來試試,小編是在用 fiddler 抓包後肯定了這一點,最後測試發現只要帶上 header 中的 referer 就可以訪問

而這個 referer 也是有講究的,這個後面跟的奇怪的參數正是上述中你們都快忘了的 key ,這個是每個 lesson 中都有的

所以對於這種情況,之後只要把請求 MP4 鏈接後的內容以二進制方式保存就行

此外還要注意對於 ts 文件,在請求時的前綴是
https://vodi97egsxf.vod.126.net/vodi97egsxf/

而在合併 ts 文件時,我用的是通過Python調用 windows 自帶的合成的命令來合成,但是需要注意合成時候的文件名一定按 001,002,...,010,...,099,100...如此排列;而如果按 1,2,3,...,10,11,...,99,100 則合並不會成功

所以在保存時就應該注意指定文件的名稱即可

好了看到這裏相信你應該有了一個基本的認識了,需要完整源碼的也可以聯繫小編

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章