基于Python制作B站視頻下載小工具
1. 原理簡(jiǎn)介
原理很簡(jiǎn)單,就是獲取視頻資源的源地址,然后爬取視頻的二進(jìn)制內(nèi)容,再寫(xiě)入到本地即可。
2. 網(wǎng)頁(yè)分析
打開(kāi)該網(wǎng)頁(yè),然后F12進(jìn)入開(kāi)發(fā)者模式,接著點(diǎn)開(kāi)網(wǎng)絡(luò)—>全部,因?yàn)橐曨l資源一般比較大,我這里根據(jù)大小進(jìn)行了從大到小的排序,找到了第一條這些可能和視頻源地址有關(guān)。
然后,我們復(fù)制找到的這條里的url部分不變的部分,回到元素中ctrl+F搜索,找到了可能和視頻源地址有關(guān)的節(jié)點(diǎn)。
果然,我們復(fù)制這部分內(nèi)容,用json在線(xiàn)解析工具發(fā)現(xiàn)真的有我們需要的看似視頻文件所在的地址。
然后,我復(fù)制這個(gè)地址用瀏覽器打開(kāi)發(fā)現(xiàn)提示403了。。
不過(guò),沒(méi)關(guān)系。。我們看接下來(lái)的操作!
3. 視頻爬取
在網(wǎng)頁(yè)分析部分,我們可以在視頻的B站地址網(wǎng)頁(yè)源代碼里通過(guò)各種數(shù)據(jù)解析的方式來(lái)獲取視頻文件的源地址,這里我采用的是正則表達(dá)式。
import?requests import?re import?json? url?=?'https://www.bilibili.com/video/BV1BU4y1H7E3' headers?=?{ ????"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/87.0.4280.66?Safari/537.36", ????"referer":?"https://www.bilibili.com" ????} resp?=?requests.get(url,?headers=headers) palyinfo?=?re.findall(r'<script>window.__playinfo__=(.*?)</script>',?resp.text)[0] palyinfo_data?=?json.loads(palyinfo)
由于正在表達(dá)式獲取的結(jié)果是字符串,而實(shí)際上它是json(字典),所以這里需要再引入json庫(kù)來(lái)進(jìn)行轉(zhuǎn)化。
我們?cè)俜治鰯?shù)據(jù),可以發(fā)現(xiàn)最終視頻文件的信息,直接key-value操作就行了。比較有意思的是視頻和音頻文件是分開(kāi)的,我們需要分別爬取后再合并即可。
#?視頻與音頻文件地址 video_url?=?json_data['data']['dash']['video'][0]['base_url'] audio_url?=?json_data['data']['dash']['audio'][0]['base_url']
有朋友可能會(huì)發(fā)現(xiàn),base_url貌似有好多個(gè)。是的,因?yàn)橐曨l清晰度有很多種嘛。這里我選取的是第一種超清 4K,大家可以根據(jù)自己需求進(jìn)行選擇!
當(dāng)然了,我們把視頻存入本地的時(shí)候還需要起個(gè)名字,這里隨便找個(gè)節(jié)點(diǎn)解析出文件名就行了。
#?視頻標(biāo)題 title?=?re.findall(r'<h1?title="(.*?)"?class="video-title">',?resp.text)[0]
4. 存入本地
既然我們已經(jīng)解析獲得了視頻的文件地址、音頻地址和文件名,那么直接就安排下載吧!
不過(guò),我們?cè)诰W(wǎng)頁(yè)分析的時(shí)候發(fā)現(xiàn)直接打開(kāi)視頻和音頻文件地址會(huì)提示403,那么因?yàn)樘^(guò)去的來(lái)源不明確導(dǎo)致的,只需調(diào)整請(qǐng)求頭為如下即可:
headers?=?{ ????"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/87.0.4280.66?Safari/537.36", ????#?加上referer即可 ????"referer":?"https://www.bilibili.com" ????}
搞定這些玩意后,我們就開(kāi)始寫(xiě)文件寫(xiě)入本地的函數(shù)吧!
#?一般視頻是mp4,音頻是mp3 def?down_file(file_url,?file_type): ????headers?=?{ ????????"User-Agent":?"Mozilla/5.0?(Windows?NT?10.0;?Win64;?x64)?AppleWebKit/537.36?(KHTML,?like?Gecko)?Chrome/87.0.4280.66?Safari/537.36", ????????"referer":?"https://www.bilibili.com" ????????} ????resp?=?requests.get(url?=?file_url,?headers=headers) ????print(resp.status_code) ???? ????print(f'文件名稱(chēng):{title}') ????#?設(shè)置單次寫(xiě)入數(shù)據(jù)的塊大小 ????chunk_size?=?1024 ????#?獲取文件大小 ????file_size?=?int(resp.headers['content-length']) ????#?用于記錄已經(jīng)下載的文件大小 ????done_size?=?0 ????#?將文件大小轉(zhuǎn)化為MB ????file_size_MB?=?file_size?/?1024?/?1024 ????print(f'文件大?。簕file_size_MB:0.2f}?MB') ????start_time?=?time.time() ????with?open(title?+?'.'?+?file_type,?mode='wb')?as?f: ????????for?chunk?in?resp.iter_content(chunk_size=chunk_size): ????????????f.write(chunk) ????????????done_size?+=?len(chunk) ????????????print(f'\r下載進(jìn)度:{done_size/file_size*100:0.2f}%',end='') ????end_time?=?time.time() ????cost_time?=?end_time-start_time ????print(f'\n累計(jì)耗時(shí):{cost_time:0.2f}?秒') ????print(f'下載速度:{file_size_MB/cost_time:0.2f}M/s')
運(yùn)行結(jié)果:
# 視頻下載
>>>down_file(video_url, 'mp4')
200
文件名稱(chēng):【咒術(shù)回戰(zhàn)】第20集五條悟帥的有些過(guò)分了
文件大?。?2.10 MB
下載進(jìn)度:100.00%
累計(jì)耗時(shí):5.72 秒
下載速度:7.36M/s
# 音頻下載
>>>down_file(audio_url, 'mp3')
200
文件名稱(chēng):【咒術(shù)回戰(zhàn)】第20集五條悟帥的有些過(guò)分了
文件大小:5.13 MB
下載進(jìn)度:100.00%
累計(jì)耗時(shí):0.80 秒
下載速度:6.42M/s
我們?cè)诒镜乜梢钥吹较螺d成功的視頻文件:
由于視頻和音頻是分開(kāi)的,所以單獨(dú)打開(kāi)這個(gè)視頻是沒(méi)有聲音的,我們需要進(jìn)行合并操作。
合并操作需要用到moviepy
庫(kù),關(guān)于這個(gè)庫(kù)我們后續(xù)也會(huì)介紹它的更多應(yīng)用,敬請(qǐng)期待~
from?moviepy?import?* from?moviepy.editor?import?* video_path?=?title?+?'.mp4' audio_path?=?title?+?'.mp3' #?讀入視頻 video?=?VideoFileClip(video_path) #?提取音軌 audio?=?AudioFileClip(audio_path) #?將音軌合并到視頻中 video?=?video.set_audio(audio) #?輸出 video.write_videofile(f"{title}(含音頻).mp4")
就這樣搞定了:
Moviepy - Building video 【咒術(shù)回戰(zhàn)】第20集五條悟帥的有些過(guò)分了(含音頻).mp4. MoviePy - Writing audio in 【咒術(shù)回戰(zhàn)】第20集五條悟帥的有些過(guò)分了(含音頻)TEMP_MPY_wvf_snd.mp3 MoviePy - Done. Moviepy - Writing video 【咒術(shù)回戰(zhàn)】第20集五條悟帥的有些過(guò)分了(含音頻).mp4 Moviepy - Done ! Moviepy - video ready 【咒術(shù)回戰(zhàn)】第20集五條悟帥的有些過(guò)分了(含音頻).mp4
5. GUI工具制作
這個(gè)吧,就是用我常用的pysimplegui
來(lái)操作了,比較簡(jiǎn)單。
import?PySimpleGUI?as?sg #?主題設(shè)置 sg.theme('SystemDefaultForReal') #?布局設(shè)置 layout?=?[[sg.Text('選擇B站視頻地址:',font=("微軟雅黑",?12)),sg.InputText(key='url',size=(50,1),font=("微軟雅黑",?10),enable_events=True)?], ??????????#?[sg.Output(size=(66,?8),font=("微軟雅黑",?10))],?? ???????????[sg.Button('開(kāi)始下載',font=("微軟雅黑",?10),button_color?='Orange'), ???????????sg.Button('關(guān)閉程序',font=("微軟雅黑",?10),button_color?='red'),] ??????????]?????? #?創(chuàng)建窗口 window?=?sg.Window('B站視頻下載工具',?layout,font=("微軟雅黑",?12),default_element_size=(50,1))???? #?事件循環(huán) while?True: ????event,?values?=?window.read() ????if?event?in?(None,?'關(guān)閉程序'): ????????break ????if?event?==?'開(kāi)始下載': ????????url?=?values['url'] ????????print('獲取視頻信息') ????????title,?video_url,?audio_url?=?get_file_info(url) ????????print('下載視頻資源') ????????down_file(title,?video_url,?'mp4') ????????print('下載音頻資源') ????????down_file(title,?audio_url,?'mp3')??? ????????print('合并視頻與音頻') ????????merge(title) ????????print('有音頻視頻處理完成') window.close()
以上就是基于Python制作B站視頻下載小工具的詳細(xì)內(nèi)容,更多關(guān)于Python B站視頻下載的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python虛擬環(huán)境virtualenv創(chuàng)建及使用過(guò)程圖解
這篇文章主要介紹了Python虛擬環(huán)境virtualenv創(chuàng)建及使用過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12python manage.py runserver流程解析
這篇文章主要介紹了python manage.py runserver流程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11利用Python實(shí)現(xiàn)面部識(shí)別的方法詳解
人臉識(shí)別正在成為軟件開(kāi)發(fā)中的一種趨勢(shì)。它有助于識(shí)別人臉并使應(yīng)用程序更加健壯。本文將使用python和face_recognition庫(kù)創(chuàng)建一個(gè)簡(jiǎn)單的人臉識(shí)別,需要的可以參考一下2022-05-05Python量化交易實(shí)戰(zhàn)之使用Resample函數(shù)轉(zhuǎn)換“日K”數(shù)據(jù)
resample函數(shù)是Python數(shù)據(jù)分析庫(kù)Pandas的方法函數(shù),它主要用于轉(zhuǎn)換時(shí)間序列的頻次,今天通過(guò)本文給大家分享python使用Resample函數(shù)轉(zhuǎn)換時(shí)間序列的相關(guān)知識(shí),感興趣的朋友一起看看吧2021-06-06python自動(dòng)提取文本中的時(shí)間(包含中文日期)
這篇文章主要介紹了python自動(dòng)提取文本中的時(shí)間(包含中文日期),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08快速進(jìn)修Python指南之網(wǎng)絡(luò)編程及并發(fā)編程
這篇文章主要為大家介紹了Java開(kāi)發(fā)者如何快速進(jìn)修Python指南之網(wǎng)絡(luò)編程及并發(fā)編程實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12