Python3 網絡爬蟲(四):視頻下載,那些事兒!

Python3 網絡爬蟲(四):視頻下載,那些事兒!

一、前言

你知道的視頻下載“姿勢”,有哪些嗎?

本文絕對有你意想不到的玩法!

PS:文中出現的所有代碼,均可在我的 Github 上下載:點擊查看

二、陳年往事

視頻下載,跟圖片下載其實並無差別,甚至更簡單。

玩過視頻下載的,應該對「you-get」並不陌生。

「you-get」支持各大視頻網站的視頻下載,國內外加起來近 80 家。像國內的愛奇藝、騰訊視頻、抖音、快手、B站、A站,國外的 Youtube、Twitter、TED、Instagram等等。

你只需要一行命令,就可以輕鬆下載想要的視頻。

you-get https://www.bilibili.com/video/BV1NZ4y1j7nw

比如,下載“黑人擡棺原版視頻”。

簡單好用!

URL:https://github.com/soimort/you-get

有了「you-get」就“無敵”了嗎?

並非如此,「you-get」對於短視頻下載較好。對於愛奇藝、騰訊視頻裏面的長視頻內容,支持就有些侷限。比如 VIP 付費內容,只能下載個 6 分鐘時長的片頭。

付費的 VIP 內容,也可以下載嗎?

當然可以。

早在 2 年前,我就搭建過視頻解析網站。

甭管是愛奇藝、騰訊、還是優酷,也甭管是免費視頻還是付費視頻,只要給個視頻網址鏈接,分分鐘解析播放。

用自己搭建的這個解析網站,白嫖了半年的視頻。後來,用我這個網站看視頻的人越來越多,索性就給它停了。

說實話,自己白嫖就算了,還帶着大家一起白嫖,就有些過分了。

後來付費意識逐漸增強,不想再做白嫖黨,也就辦了愛奇藝的年度會員。

這種視頻解析網站現在仍然有很多,但大多數都早已不能用了。

在網絡上,有個叫「視頻解析接口」的東西

這些大大小小的視頻解析網站,其實就是調用的這些第三方「視頻解析接口」實現的。

背後的原理也並不複雜,就是拿着一些 VIP 會員賬號,在後臺解析視頻,然後分享給別人看的。

隨着版權意識、版權管理的加強,以及技術的更新迭代,這類「視頻解析接口」也就逐漸失效了。

在網絡上,還有個叫「資源採集網」的東西。

「視頻解析接口」大量失效,那幫搞「灰產」的人另闢蹊徑,既然視頻無法解析,那就搜索資源吧。

現在,與其叫它們「視頻解析接口」,不如叫它們「視頻搜索接口」。

這些「視頻搜索接口」拿着視頻地址,去「資源採集網」匹配資源。

「資源採集網」其實就是一個大型網絡爬蟲,它會採集網絡上的視頻資源,並將它們整合到一起。

這裏的說頭,太多了。扯遠了,迴歸正題。

三、視頻下載

背景講完了,那就進入今天的主題,從「資源採集網」下載我們想要的視頻。

以「越獄第一季」爲例,越獄算是帶我入坑的美劇之一,Miller 太帥了。

本文要爬的網站名叫「ok 資源網」,長這樣:

Python3 網絡爬蟲(四):視頻下載,那些事兒!

 

URL:http://www.jisudhw.com/

思路也不復雜,搜索、解析、下載。

1、搜索

想要下載視頻,首先得找到資源,採用站內搜索很簡單。

抓搜索的請求包也特別簡單,教一個小技巧:

第一步輸入要搜索的內容,第二步打開並清理 Network,第三步點擊搜索按鈕。

Network 裏第一個彈出的就是搜索的請求包。

可以看到,這是一個 POST 請求。

之前的實戰內容,無論是下載小說,還是下載圖片,都是 GET 請求。

GET 請求,就是字面意思,從服務器獲取數據。POST 請求,也是字面意思,給服務器發送數據。

因爲我們是搜索嘛,得告訴服務器,咱搜索啥,給服務器傳遞數據,就是通過 POST。

能 POST 的數據有很多,可以是簡單的字符串、也可以是一張圖片。

POST 啥數據,那就看服務器要啥數據,要啥給啥,就這麼簡單。

看一下搜索的結果頁,不難發現,搜索結果存儲在 class 屬性爲 xing_vb4 的 span 標籤裏。

Python3 網絡爬蟲(四):視頻下載,那些事兒!

沒有難度啊,直接搞起。根據瀏覽器抓包結果,填寫 data 信息即可。由於網站也有簡單的 Header 反爬蟲,所以一些必要的 Headers 信息也要填寫。

import requests
from bs4 import BeautifulSoup

search_keyword = '越獄第一季'
search_url = 'http://www.jisudhw.com/index.php'
serach_params = {
    'm': 'vod-search'
}
serach_headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36',
    'Referer': 'http://www.jisudhw.com/',
    'Origin': 'http://www.jisudhw.com',
    'Host': 'www.jisudhw.com'
}
serach_datas = {
    'wd': search_keyword,
    'submit': 'search'
}

r = requests.post(url=search_url, params=serach_params, headers=serach_headers, data=serach_datas)

r.encoding = 'utf-8'
server = 'http://www.jisudhw.com'
search_html = BeautifulSoup(r.text, 'lxml')
search_spans = search_html.find_all('span', class_='xing_vb4')
for span in search_spans:
    url = server + span.a.get('href')
    name = span.a.string
    print(name)
    print(url)

順利拿到詳情頁地址:

Python3 網絡爬蟲(四):視頻下載,那些事兒!

2、解析

解析詳情頁,獲得下載鏈接,我們先看下詳情頁都有啥。

URL:http://www.jisudhw.com/?m=vod-detail-id-15409.html

視頻詳情頁,至少有兩種播放類型,一種是 m3u8 ,一種是 kuyun 。

Python3 網絡爬蟲(四):視頻下載,那些事兒!

拿到其中一種鏈接即可,我們以 m3u8 爲例進行說明。

可以看到,視頻鏈接都放在了 input 標籤裏,直接匹配:

import requests
from bs4 import BeautifulSoup

detail_url = 'http://www.jisudhw.com/?m=vod-detail-id-15409.html'
r = requests.get(url = detail_url)
r.encoding = 'utf-8'
detail_bf = BeautifulSoup(r.text, 'lxml')
num = 1
serach_res = {}
for each_url in detail_bf.find_all('input'):
    if 'm3u8' in each_url.get('value'):
        url = each_url.get('value')
        if url not in serach_res.keys():
            serach_res[url] = num
        print('第%03d集:' % num)
        print(url)
        num += 1

將結果都存放到了字典裏,這樣方便後續視頻鏈接和視頻名稱的一一對應。

Python3 網絡爬蟲(四):視頻下載,那些事兒!

3、下載

視頻下載,一般而言,無非兩種情況。

一種,鏈接明確是以 mp4、mkv、rmvb 這類視頻格式後綴爲結尾的鏈接,這種下載很簡單,跟圖片下載方法一樣,就是視頻文件要比圖片大而已。

另一種,鏈接是以 m3u8 這類分段視頻後綴結尾的鏈接。啥是分段視頻?

抓包看一下就知道了,打開視頻播放鏈接:

http://youku.com-youku.net/share/f0d48bde60d407c45af7ca00d1ef927b

Python3 網絡爬蟲(四):視頻下載,那些事兒!

現在很多視頻都是分段存儲的,你看視頻的時候,其實是在加載一個個 ts 視頻片段,一個片段是幾秒鐘的視頻。

這種視頻要怎麼下載?怎麼將 ts 視頻片段組合成一個視頻?

其實,如果知道方法,就很簡單。

m3u8 這種格式的視頻,就是由一個個 ts 視頻片段組成的。

一個 m3u8 文件並不大,你可以把它理解爲鏈表,每個 ts 視頻片段文件,都有下一個時序的 ts 視頻片段的地址。

Python3 網絡爬蟲(四):視頻下載,那些事兒!

記住一點,解決音頻和視頻的一些問題,可以看看 FFmpeg,它的中文名叫多媒體視頻處理工具。

FFmpeg 有非常強大的功能包括視頻採集、視頻格式轉換、視頻抓圖、給視頻加水印等功能。

這種 ts 視頻片段合成,格式轉換問題,交給 FFmpeg 就好了。

要使用 FFmpeg,需要先安裝配置一番。

下載地址:https://ffmpeg.zeranoe.com/builds/

安裝好後,記得配置環境變量。

FFmpeg 也有 Python API 接口,名字叫 ffmpy3,安裝好 FFmpeg 後,可以直接通過 pip 安裝。

pip install ffmpy3

都弄好,就可以愉快的玩耍了。

比如想要下載 m3u8 文件。

URL:http://youku.com-youku.net/20180614/11920_4c9e1cc1/index.m3u8

可以在命令行輸入如下指令:

ffmpeg -i "http://youku.com-youku.net/20180614/11920_4c9e1cc1/index.m3u8" "第001集.mp4"

視頻會保存爲「第001集.mp4」。

如果用 Python 接口,也只需要兩行代碼:

import ffmpy3
ffmpy3.FFmpeg(inputs={'http://youku.com-youku.net/20180614/11920_4c9e1cc1/index.m3u8': None}, outputs={'第001集.mp4':None}).run()

FFmpeg 自動整合 ts 分段視頻,並保存爲 mp4 格式的視頻。

是不是很簡單?

四、整合代碼

代碼整合在一起,開始下載電視劇。

import os
import ffmpy3
import requests
from bs4 import BeautifulSoup
from multiprocessing.dummy import Pool as ThreadPool

search_keyword = '越獄第一季'
search_url = 'http://www.jisudhw.com/index.php'
serach_params = {
    'm': 'vod-search'
}
serach_headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.122 Safari/537.36',
    'Referer': 'http://www.jisudhw.com/',
    'Origin': 'http://www.jisudhw.com',
    'Host': 'www.jisudhw.com'
}
serach_datas = {
    'wd': search_keyword,
    'submit': 'search'
}


video_dir = ''
    
r = requests.post(url=search_url, params=serach_params, headers=serach_headers, data=serach_datas)
r.encoding = 'utf-8'
server = 'http://www.jisudhw.com'
search_html = BeautifulSoup(r.text, 'lxml')
search_spans = search_html.find_all('span', class_='xing_vb4')
for span in search_spans:
    url = server + span.a.get('href')
    name = span.a.string
    print(name)
    print(url)
    video_dir = name
    if name not in os.listdir('./'):
        os.mkdir(name)
        
    detail_url = url
    r = requests.get(url = detail_url)
    r.encoding = 'utf-8'
    detail_bf = BeautifulSoup(r.text, 'lxml')
    num = 1
    serach_res = {}
    for each_url in detail_bf.find_all('input'):
        if 'm3u8' in each_url.get('value'):
            url = each_url.get('value')
            if url not in serach_res.keys():
                serach_res[url] = num
            print('第%03d集:' % num)
            print(url)
            num += 1

def downVideo(url):
    num = serach_res[url]
    name = os.path.join(video_dir, '第%03d集.mp4' % num)
    ffmpy3.FFmpeg(inputs={url: None}, outputs={name:None}).run()
            
# 開8個線程池
pool = ThreadPool(8)
results = pool.map(downVideo, serach_res.keys())
pool.close()
pool.join()

由於視頻太大了,要是一個一個地下載,有些慢,適當開個線程,8 線程下載。

Python3 網絡爬蟲(四):視頻下載,那些事兒!

來吧,一起看「越獄」吧!

五、最後

本文僅是探討一些關於視頻下載的技術,切勿濫用。

支持正版,從我做起。

 

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