一、寫在前面
1、關于音頻視訊合并
因為小破站的音頻和視訊畫面是分開的 (番劇也是一樣的),正常爬下來是這樣。

額,這麼截圖,小姐姐的臉都變形了…
本來還是挺好看的一姑娘,算了不管她。
是以我們需要額外的去安裝一個軟體
FFmpeg
用來合成視訊,然後配置環境變量就可以了。
2、關于打包exe檔案
這是我打包好的樣子
正常打包後是沒有我這個圖示的,圖示在打包的時候可以一起改了。
二、過程結果
合成過程
合成成功
這個封面着實不給力,大家自己去試的時候,換一個吧…
三、代碼實作
首先導入子產品
import requests # 資料請求子產品 第三方子產品 pip install requests
import re # 正規表達式 内置子產品 不需要安裝
import pprint # 格式化輸出子產品
import json # 序列化和反序列化
import subprocess
import os
複制
發送請求 以及擷取資料函數
#單引号/雙引号/三引号括起來的内容是字元串資料。
#三引号也可以作為注釋,多行代碼注釋。
def get_response(html_url):
"""
:param html_url: 請求的url位址
:return: 傳回請求伺服器傳回的響應資料
"""
# 在發送請求之前, 需要進行僞裝 headers 請求頭
# user-agent 浏覽器基本辨別 使用者代理 基本僞裝 反反爬的手段
# 出現 403 加防盜鍊 referer 告訴伺服器, 我們發送請求的url位址 是從哪裡跳轉過來的
headers = {
'referer': 'https://search.bilibili.com/',
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
}
response = requests.get(url=html_url, headers=headers) # 請求代碼
# <Response [200]> 對象response響應對象 200 狀态碼 表示請求成功
# 404 >>> 你所撥打的電話是空号 >>> 網址出錯
# 403 >>> 你所撥打的電話不在服務區 >>> 你沒有通路權限
# 100-500 300還行
return response
複制
擷取視訊标題 / 音頻 url位址 / 視訊畫面url位址
def get_video_info(html_url):
"""
:param html_url: 視訊的詳情頁
:return: 視訊标題 / 音頻 url位址 / 視訊畫面url位址
"""
response = get_response(html_url=html_url)
# response.text 擷取響應體的文本資料
# print(response.text) 擷取html字元串資料
# 隻要你可以看到資料 就可以下載下傳 進行批量下載下傳
# 解析資料 提取視訊标題 re正規表達式 css選擇器 xpath(解析方式) bs4 parsel lxml (解析子產品) jsonpath 主要提取json資料
# ['【4K美女】此視訊禁止曹賊入内~~'] 正規表達式提取的資料内容 傳回都是清單資料類型 [0] 清單 索引取值
# 通過re正規表達式裡面findall 方法 提取資料内容 '<h1 title="(.*?)" class="video-title">' 我想要的提取資料
# 想要的内容用括号括起來 .*? 可以比對任意字元(除了換行符以外\n) 從 response.text 裡面查找資料
title = re.findall('<h1 title="(.*?)" class="video-title">', response.text)[0].replace(' ', '') # 标題
title = re.sub(r'[/\*:"?<>|]', '', title)
html_data = re.findall('<script>window.__playinfo__=(.*?)</script>', response.text)[0] # 播放資訊的
# html_data 是什麼樣的資料類型 <class 'str'>
# 為了更加友善提取資料, 可以字元串資料 轉換成 字典資料類型
# print(type(response.text))
# print(title)
# print(html_data)
# pprint.pprint(html_data)
# print(type(html_data))
json_data = json.loads(html_data)
# 根據冒号左邊的内容, 提取冒号右邊的内容 鍵值對取值
# 新增賬號 電話号碼 或者 身份證号碼 數字個數是多的吧 然後不能瞎填
audio_url = json_data['data']['dash']['audio'][0]['baseUrl']
video_url = json_data['data']['dash']['video'][0]['baseUrl']
video_info = [title, audio_url, video_url]
# pprint.pprint(json_data)
# print(audio_url)
# print(video_url)
return video_info
複制
儲存資料函數
def save(title, audio_url, video_url):
"""
:param title: 視訊标題
:param audio_url: 音頻url
:param video_url: 視訊畫面url
:return:
"""
# 儲存音頻 視訊資料 擷取二進制資料内容
# 403 沒有通路的權限
audio_content = get_response(html_url=audio_url).content
video_content = get_response(html_url=video_url).content
# 英文符号
with open(title + '.mp3', mode='wb') as f:
f.write(audio_content)
with open(title + '.mp4', mode='wb') as f:
f.write(video_content)
print(title, '儲存成功~~~')
複制
資料的合并
def merge_data(video_name):
print('視訊合成開始:', video_name)
cmd = f"ffmpeg -i {video_name}.mp4 -i {video_name}.mp3 -c:v copy -c:a aac -strict experimental {video_name}output.mp4"
# print(cmd)
subprocess.run(cmd, shell=True)
print('視訊合成結束:', video_name)
os.remove(f'{video_name}.mp4')
os.remove(f'{video_name}.mp3')
複制
如果運作沒儲存,但是沒有下載下傳結果的話,就是你的環境變量沒設定好,我們把合并程式的檔案路徑放上去就行了。
cmd = f"C:\\ffmpeg\\bin\\ffmpeg -i
複制
擷取某一個up主所有視訊bv号
def get_video_id(html_url):
"""
:param html_url: 視訊資訊資料包
:return:
"""
json_data = get_response(html_url).json()['data']['list']['vlist']
bv_id_list = [i['bvid'] for i in json_data]
return bv_id_list
複制
主函數
def main(html_url):
"""
:param bv_id: bv号
:return:
"""
bv_id_list = get_video_id(html_url)
for index in bv_id_list:
url = f'https://www.bilibili.com/video/{index}'
video_info = get_video_info(url) # [title, audio_url, video_url]
save(video_info[0], video_info[1], video_info[2])
merge_data(video_info[0])
if __name__ == '__main__':
for page in range(1, 5):
url = f'https://api.bilibili.com/x/space/arc/search?mid=81595107&ps=30&tid=0&pn={page}&keyword=&order=pubdate&jsonp=jsonp'
main(url)
複制
兄弟們悠着點,看多了遭不住。
兄弟們,學廢了嗎?
覺得還行的話,記得三連哈~