送書(shū) | 教你下載B站指定視頻
大家好!我是啃書(shū)君!
不知道大家有沒(méi)有下載自己喜歡的視頻的習(xí)慣,反正我就有。眾所周知,b站是一個(gè)很好的學(xué)習(xí)知識(shí)平臺(tái),我們可以在b站學(xué)習(xí)各種各樣的知識(shí),但唯一的不足是b站沒(méi)有提供下載視頻的功能,遇到喜歡的只能點(diǎn)贊、關(guān)注、收藏,那么我們想下載指定的視頻該怎么辦呢,今天將教你下載b站指定視頻?。?!
爬前準(zhǔn)備
在爬前指定視頻數(shù)據(jù)并下載指定視頻之前,我們需要用到以下庫(kù)、模塊、第三方工具:
-
requests庫(kù):用來(lái)發(fā)送網(wǎng)絡(luò)請(qǐng)求; -
os模塊:用來(lái)處理文件和目錄; -
parsel庫(kù):是Scrapy 開(kāi)發(fā)團(tuán)隊(duì)開(kāi)源的一個(gè)支持 XPath和 CSS 選擇器語(yǔ)法的網(wǎng)頁(yè)解析庫(kù),用來(lái)將文本數(shù)據(jù)轉(zhuǎn)換為XPath可以解析的HTML文本; -
re庫(kù):正則解析庫(kù),主要用于字符串匹配; -
FFmpeg第三方工具:用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源第三方工具,我們這里主要用來(lái)純音頻和純視頻的拼接。
相信大家對(duì)上面前四個(gè)庫(kù)與模塊已經(jīng)很熟悉了,安裝方式也很簡(jiǎn)單,執(zhí)行pip install 庫(kù)名即可,所以這里我們主要介紹FFmpeg第三方工具。
FFmpeg第三方工具簡(jiǎn)介
FFmpeg是一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源第三方工具。它包括了領(lǐng)先的音/視頻編碼庫(kù)libavcodec等。可以輕易地實(shí)現(xiàn)多種視頻格式之間的相互轉(zhuǎn)換。包括如下幾個(gè)部分:
-
libavformat:用于各種音視頻封裝格式的生成和解析,包括獲取解碼所需信息以生成解碼上下文結(jié)構(gòu)和讀取音視頻幀等功能; -
libavcodec:用于各種類型聲音/圖像編解碼; -
libavutil:包含一些公共的工具函數(shù); -
libswscale:用于視頻場(chǎng)景比例縮放、色彩映射轉(zhuǎn)換; -
libpostproc:用于后期效果處理; -
ffmpeg:該項(xiàng)目提供的一個(gè)工具,可用于格式轉(zhuǎn)換、解碼或電視卡即時(shí)編碼等; -
ffsever:一個(gè) HTTP 多媒體即時(shí)廣播串流服務(wù)器; -
ffplay:是一個(gè)簡(jiǎn)單的播放器,使用ffmpeg 庫(kù)解析和解碼,通過(guò)SDL顯示; -
ffprobe:收集多媒體文件或流的信息,并以人和機(jī)器可讀的方式輸出。
FFmpeg第三方工具就介紹到這里,下面我們開(kāi)始安裝與配置FFmpeg
FFmpeg第三方工具安裝與配置
首先我們進(jìn)入FFmpeg官網(wǎng),如下圖所示:
注意:這里有個(gè)小坑,就是可能有不少人會(huì)直接點(diǎn)擊Download Source Code并進(jìn)行下載,下載并解壓后,得到的是其源代碼及一些配置程序,如下圖所示:
這些文件和程序?qū)ξ覀儧](méi)多大用,我們需要的是包和可執(zhí)行文件。
下載包和可執(zhí)行文件
點(diǎn)擊Download Source Code并進(jìn)行下載得到的是源代碼,我們需要的是包和可執(zhí)行文件,所以正確的下載方式如下圖所示:
大家可以根據(jù)自己的操作系統(tǒng)來(lái)下載對(duì)應(yīng)的壓縮包,點(diǎn)擊圖中的3后,就會(huì)跳轉(zhuǎn)如下網(wǎng)頁(yè):
我們往下拉頁(yè)面找到release builds,如下圖所示:
我這里是下載以前版本的壓縮包,如上圖的紅框所示,下載完畢,解壓文件,進(jìn)入bin目錄。如下圖所示:
設(shè)置環(huán)境變量
只下載包和可執(zhí)行文件是沒(méi)多大用的,我們還需要設(shè)置環(huán)境變量,設(shè)置環(huán)境變量方法很簡(jiǎn)單。
首先進(jìn)入剛剛解壓的文件,進(jìn)入bin目錄,把其路徑復(fù)制下來(lái),如下圖所示:
然后點(diǎn)擊“系統(tǒng)屬性->環(huán)境變量->系統(tǒng)變量”,選擇“Path”條目,點(diǎn)擊“編輯->新建”,把剛才的bin文件夾路徑復(fù)制粘貼進(jìn)去,點(diǎn)擊確定即可。如下圖所示:
好了,環(huán)境變量已經(jīng)設(shè)置好了,接下來(lái)開(kāi)始測(cè)試FFmpeg是否安裝并配置成功。
我們打開(kāi)cmd命令行窗口,輸入命令“ffmpeg –version”。窗口返回ffmpeg的版本信息,說(shuō)明安裝成功,如下圖所示:
好了,F(xiàn)Fmpeg第三方工具的安裝和配置就講到這里,接下來(lái)我們正式開(kāi)始爬取工作。
網(wǎng)頁(yè)分析
首先我們進(jìn)入b站,隨便點(diǎn)擊一個(gè)愉悅視頻并打開(kāi)開(kāi)發(fā)者工具,如下圖所示:
通常情況下,我們通過(guò)檢查元素來(lái)定位頁(yè)面的數(shù)據(jù)信息的存放位置,如下圖所示:
假如左邊的紅框是一張圖片的話,我們很容易就可以在右邊的紅框找到其圖片的URL鏈接,經(jīng)過(guò)一番的尋找,并沒(méi)有發(fā)現(xiàn)對(duì)我們有用的視頻URL鏈接,那么怎么辦好呢,是不是爬不了了。
這時(shí)我們可以換個(gè)思路,一般情況下,幾乎所有的視頻網(wǎng)站都可以選擇視頻清晰度來(lái)播放,如下圖所示:
那么我們可以考慮嘗試在代碼元素中搜索超清,看看能不能搜到和視頻鏈接相關(guān)的數(shù)據(jù),如下圖所示:
我們發(fā)現(xiàn)搜索超清有兩個(gè)匹配項(xiàng),經(jīng)過(guò)簡(jiǎn)單的判斷,我們發(fā)現(xiàn)第一個(gè)匹配項(xiàng)中有個(gè)參數(shù)名為window.playinfo,翻譯出來(lái)的大概意思是播放信息,播放信息中,一般都會(huì)存放播放視頻的url鏈接,經(jīng)過(guò)簡(jiǎn)單的查找,果然在里面找到我們的想要的url鏈接,如下圖所示:
細(xì)心的小伙伴就發(fā)現(xiàn)了id的參數(shù)值對(duì)應(yīng)著視頻的清晰度,其中,超清4k對(duì)應(yīng)的id值為120,高清1080P60對(duì)應(yīng)的id值為116,由于我們不是b站的大會(huì)員,最高清晰度只能選擇1080P高清,所以對(duì)應(yīng)的id為80。
圖中方框的video表示視頻,那么問(wèn)題來(lái)了,那audio音頻在哪里找呢?我們繼續(xù)用剛才的搜索方法,搜索audio,如下圖所示:
我們發(fā)現(xiàn),audio音頻的存放位置是在我們剛才找到的video存放位置之中,這樣就好辦了,現(xiàn)在video視頻和audio音頻的URL鏈接都知道在哪里了,接下來(lái)我們正式開(kāi)始編寫爬蟲(chóng)來(lái)下載我們想要的視頻。
實(shí)戰(zhàn)演練
我們的基本爬取并下載視頻的思路是:
-
發(fā)送網(wǎng)絡(luò)請(qǐng)求; -
提取視頻的名字、video純視頻鏈接和audio純音頻鏈接; -
下載video純視頻和audio純音頻; -
拼接完整的視頻。
發(fā)送網(wǎng)絡(luò)請(qǐng)求
首先我們發(fā)送網(wǎng)絡(luò)請(qǐng)求,發(fā)送網(wǎng)絡(luò)請(qǐng)求最重要的是什么,沒(méi)錯(cuò)就是要有URL鏈接,那么URL鏈接是哪個(gè)呢,URL鏈接就是我們視頻頁(yè)的URL鏈接,如下圖所示:
具體代碼如下所示:
url = 'https://www.bilibili.com/video/BV17U4y1j7Sz?spm_id_from=333.851.b_7265636f6d6d656e64.6'
headers={
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
'referer': url
}
def get_parse():
response = requests.get(url, headers=headers)
data = response.text
get_data(data)
首先我們創(chuàng)建一個(gè)變量url來(lái)存放發(fā)送網(wǎng)絡(luò)請(qǐng)求的URL,再定義get_parse()方法來(lái)發(fā)送網(wǎng)絡(luò)請(qǐng)求、獲取響應(yīng)數(shù)據(jù)并將數(shù)據(jù)傳遞給自定義的get_data()方法中。當(dāng)我們想要下載其他的視頻時(shí),只要修改url鏈接即可。
提取視頻名及獲取視頻音頻URL
在上一步中,我們成功發(fā)送了網(wǎng)絡(luò)請(qǐng)求并將網(wǎng)絡(luò)請(qǐng)求響應(yīng)數(shù)據(jù)返回到自定義方法get_data()中,接下來(lái)我們將提取視頻名及視頻音頻的URL鏈接,具體代碼如下所示:
def get_data(data):
Xpath = parsel.Selector(data)
title = Xpath.xpath('//*[@id="viewbox_report"]/h1/span/text()').extract_first()
playinfo = Xpath.xpath('/html/head/script[5]/text()').extract_first()
video_url = re.findall(r'"video":.*?,"baseUrl":"(.*?)",', playinfo)[0]
audio_url = re.findall(r'"audio":.*?,"baseUrl":"(.*?)",', playinfo)[0]
download(video_url,audio_url,title)
首先利用parsel.Selector()方法把get_data()接收到的文本數(shù)據(jù)轉(zhuǎn)換為XPath可以解析的HTML文本并通過(guò)xpath來(lái)把視頻名和播放信息提取出來(lái),再通過(guò)正則表達(dá)式將純視頻URL鏈接和純音頻URL鏈接提取出來(lái),注意re.findall()返回的是列表,所以我們通過(guò)[0]來(lái)獲取列表中的數(shù)據(jù),這樣我們得到的就是字符串。最后把視頻名和純視頻音頻的URL傳遞給自定義方法download()中。
下載視頻音頻
在上一步中,我們成功提取并傳遞視頻名和純視頻音頻的URL到自定義方法download()中,接下來(lái)就要下載視頻了,具體代碼如下所示:
def download(video_url,audio_url,title):
video = requests.get(video_url, headers=headers).content
audio = requests.get(audio_url, headers=headers).content
title_new = title + "純"
with open(f'{title_new}.mp4', 'wb')as f:
f.write(video)
with open(f'{title_new}.mp3', 'wb')as f:
f.write(audio)
Splicing(title)
首先我們通過(guò)在上一步獲取到的URL鏈接發(fā)送網(wǎng)絡(luò)請(qǐng)求并返回響應(yīng)的字節(jié)碼,再定義一個(gè)變量來(lái)對(duì)下載的純視頻音頻進(jìn)行命名,然后將純視頻的字節(jié)碼和純音頻的字節(jié)碼寫入文件中,最后將視頻名和title_new傳遞到自定義方法Splicing()中。
不知道大家有沒(méi)有注意到,就是我們?cè)诘谝徊桨l(fā)送網(wǎng)絡(luò)請(qǐng)求中,headers請(qǐng)求頭中有一個(gè)參數(shù)referer,這個(gè)參數(shù)我們一般稱為防盜鏈。這里一定要添加referer。
圖中的錯(cuò)誤意思簡(jiǎn)單來(lái)說(shuō)就是無(wú)法拼接已經(jīng)損壞或無(wú)內(nèi)容的純音頻和純視頻,我們查看剛下載的純視頻純音頻文件,如下圖所示:
我們發(fā)現(xiàn)剛下載的純視頻純音頻文件只有1KB的大小,但幾乎沒(méi)有視頻音頻是1KB的,所以很顯然我們沒(méi)有下載到視頻音頻。那么問(wèn)題來(lái)了,明明一切很合乎常理,為什么會(huì)沒(méi)有下載到視頻音頻呢。這里就和referer防盜鏈有關(guān)。
referer防盜鏈?zhǔn)且环N簡(jiǎn)單的反爬機(jī)制,用來(lái)標(biāo)識(shí)這個(gè)請(qǐng)求是從哪個(gè)頁(yè)面發(fā)過(guò)來(lái)的,服務(wù)器可以拿到這一信息并做相應(yīng)的處理,例如做來(lái)源統(tǒng)計(jì)、防盜處理等,假如沒(méi)加防盜鏈,服務(wù)器就可能認(rèn)為你的請(qǐng)求屬于爬蟲(chóng)發(fā)送的,服務(wù)器就不給出響應(yīng)。
那么如何正確添加referer的參數(shù)呢?referer的參數(shù)存放在網(wǎng)頁(yè)的哪里呢?哪些網(wǎng)址可以作為referer參數(shù)呢?
在我看來(lái),這三個(gè)地方的網(wǎng)址都可以作為referer參數(shù),我們拿b站作為例子:
#b站首頁(yè)網(wǎng)址
'referer':'https://www.bilibili.com/'
#要爬取頁(yè)面的網(wǎng)址
'referer':'https://www.bilibili.com/video/BV14f4y1A7Xf?spm_id_from=333.851.b_7265636f6d6d656e64.6'
第三,Requeset Headers里面的referer,如下圖所示:
這里我們直接用要爬取頁(yè)面的網(wǎng)址作為referer的參數(shù)。
拼接完整的視頻
在上一步中,純音頻純視頻已經(jīng)下載后了,接下來(lái)我們開(kāi)始把視頻音頻拼接起來(lái),拼接方法很簡(jiǎn)單,具體代碼如下圖所示:
def Splicing(title,title_new):
os.system(f'ffmpeg -i "{title_new}.mp4" -i "{title_new}.mp3" -c copy "{title}.mp4"')
os.remove(f'{title_new}.mp4')
os.remove(f'{title_new}.mp3')
首先調(diào)用os.system方法,再利用ffmpeg第三方工具,其中
-
-i 文件名表示輸入文件,也就是存在你要拼接的文件; -
-c copy 文件名表示輸出文件,相當(dāng)于將純視頻純音頻文件合并在一起并導(dǎo)出。
最后純音頻純視頻文件對(duì)我們已經(jīng)沒(méi)有什么用了,這時(shí)可以調(diào)用os.remove()方法把它們移除。
程序運(yùn)行結(jié)果如下圖所示:
結(jié)果展示
好了,下載b站指定的視頻講到這里了,感謝觀看?。?!
送書(shū)
本次送書(shū)《Python高效開(kāi)發(fā)實(shí)戰(zhàn)——Django、Tornado、Flask、Twisted(第3版)》,一書(shū)本著“純碎干貨,實(shí)用至上”的原則,讓我們成為真正的全棧開(kāi)發(fā)人才。
1、講解Python Web開(kāi)發(fā),必定離不開(kāi)HTTP。有多少人知道HTTP的工作流程呢?
2、我們?cè)L問(wèn)網(wǎng)站,網(wǎng)站服務(wù)器把內(nèi)容反饋給我們。網(wǎng)站服務(wù)器是什么?
3、都說(shuō)HTTP網(wǎng)站不安全,要變成HTTPS的。如何建立HTTPS網(wǎng)站?
本文就針對(duì)以上問(wèn)題做簡(jiǎn)單解答。

本書(shū)分為3篇:上篇是Python基礎(chǔ),帶領(lǐng)初學(xué)者實(shí)踐Python開(kāi)發(fā)環(huán)境,掌握基本語(yǔ)法,同時(shí)對(duì)網(wǎng)絡(luò)協(xié)議、Web客戶端技術(shù)、數(shù)據(jù)庫(kù)建模等網(wǎng)絡(luò)編程基礎(chǔ)進(jìn)行深入淺出的學(xué)習(xí);中篇是Python框架,學(xué)習(xí)當(dāng)前***的Python Web框架,即Django、Tornado、Flask和Twisted,達(dá)到對(duì)各種Python網(wǎng)絡(luò)技術(shù)融會(huì)貫通的目的;下篇是Python框架實(shí)戰(zhàn),分別使用4種框架進(jìn)行項(xiàng)目實(shí)踐,利用其各自的特點(diǎn)開(kāi)發(fā)適用于不同場(chǎng)景的網(wǎng)絡(luò)程序。本書(shū)內(nèi)容精練、重點(diǎn)突出、實(shí)例豐富、講解通俗,是廣大網(wǎng)絡(luò)應(yīng)用設(shè)計(jì)和開(kāi)發(fā)人員不可多得的一本參考書(shū)。
點(diǎn)擊下方回復(fù):送書(shū) 即可!
你的點(diǎn)【贊】,會(huì)讓我知道,你們就是那個(gè)一直陪著我努力的人。
