Python寫一個下載B站內容的GUI工具,視頻、彈幕、評論都能下載,真的太方便了!

来源:https://www.cnblogs.com/hahaa/archive/2023/03/07/17190062.html
-Advertisement-
Play Games

今天我們分享一個用Python寫下載視頻+彈幕+評論的代碼。 之前自游寫了採集小破站視頻、彈幕、評論的代碼,還錄了視頻。 我當時就問他,你就不能把這些寫成GUI,把這些功能放到一起不是別人用起來更方便麽? 本來他還想反抗,當時我就直接叫他看著辦! 他哪受得了這種委屈,當時就乖乖寫代碼去了,現在我把代 ...


今天我們分享一個用Python寫下載視頻+彈幕+評論的代碼。

之前自游寫了採集小破站視頻、彈幕、評論的代碼,還錄了視頻。

我當時就問他,你就不能把這些寫成GUI,把這些功能放到一起不是別人用起來更方便麽?

本來他還想反抗,當時我就直接叫他看著辦!


他哪受得了這種委屈,當時就乖乖寫代碼去了,現在我把代碼分享給大家。

本次要實現的功能

咱們本次先簡單的實現一下

  • 評論
  • 彈幕
  • 視頻

效果展示

我們來看看實現效果吧

代碼實戰

主要代碼分為界面和採集部分

獲取數據

網址我屏蔽了,防止誤殺。

獲取視頻

import requests
import re
import json
from pprint import  pprint
import subprocess
import os
# 完整源碼直接加這個Q裙領取 872937351
def Video(bv_id):
    url = f'https://www.***.com/video/{bv_id}'
    headers = {
        # 防盜鏈
        'referer': 'https://www.***.com/video/',
        # 瀏覽器基本身份標識 表示瀏覽器
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
    }
    # 發送請求 ---> <Response [200]> 響應對象,  200狀態碼 表示請求成功
    response = requests.get(url=url, headers=headers)

    # 獲取視頻標題
    title = re.findall('"title":"(.*?)","pubdate"', response.text)[0].replace(' ', '')
    # 獲取視頻數據信息 前端標簽兩個兩個一起
    html_data = re.findall('<script>window.__playinfo__=(.*?)</script>', response.text)[0]
    # 轉換數據類型  字元串數據轉成json字典數據類型
    json_data = json.loads(html_data)
    # print列印字典數據, 輸出一行內容 print(json_data)
    # pprint 列印字典數據, 格式化輸出 展開效果 pprint(json_data)
    # 字典數據 B站數據 音頻和視頻分開的 根據冒號左邊的內容, 提取冒號右邊的內容 鍵值對取值
    audio_url = json_data['data']['dash']['audio'][0]['baseUrl']
    video_url = json_data['data']['dash']['video'][0]['baseUrl']
    # 403 Forbidden 沒有訪問許可權.....
    audio_content = requests.get(url=audio_url, headers=headers).content
    video_content = requests.get(url=video_url, headers=headers).content
    if not os.path.exists('video\\'):
        os.mkdir('video\\')
    with open('video\\' + title + '.mp3', mode='wb') as audio:
        audio.write(audio_content)
    with open('video\\' + title + '.mp4', mode='wb') as video:
        video.write(video_content)
    # 獲取音頻內容以及視頻畫面內容
    cmd = f"ffmpeg -i video\\{title}.mp4 -i video\\{title}.mp3 -c:v copy -c:a aac -strict experimental video\\{title}output.mp4"
    subprocess.run(cmd, shell=True)
    os.remove(f'video\\{title}.mp4')
    os.remove(f'video\\{title}.mp3')
    return title

 

採集彈幕

import requests
import re
import os

def get_response(html_url):
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
    }
    response = requests.get(url=html_url, headers=headers)
    response.encoding = response.apparent_encoding
    return response


def get_Dm_url(bv_id):
    link = f'https://www.***.com/video/{bv_id}/'
    html_data = get_response(link).text
    Dm_url = re.findall('<a href="(.*?)"  class="btn btn-default" target="_blank">彈幕</a>', html_data)[0]
    title = re.findall('<input type="text" value="(.*?)"', html_data)[-1]
    return Dm_url, title


def get_Dm_content(Dm_url, title):
    html_data = get_response(Dm_url).text
    content_list = re.findall('<d p=".*?">(.*?)</d>', html_data)
    if not os.path.exists('彈幕\\'):
        os.mkdir('彈幕\\')
    for content in content_list:
        with open(f'彈幕\\{title}彈幕.txt', mode='a', encoding='utf-8') as f:
            f.write(content)
            f.write('\n')

def main(bv_id):
    Dm_url, title = get_Dm_url(bv_id)
    get_Dm_content(Dm_url, title)

 

採集評論

import requests
import re
import os


def get_response(html_url, params=None):
    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.0.0 Safari/537.36'
    }
    response = requests.get(url=html_url, params=params, headers=headers)
    return response


def get_oid(bv_id):
    link = f'https://www.***.com/video/{bv_id}/'
    html_data = get_response(link).text
    oid = re.findall('window.__INITIAL_STATE__={"aid":(\d+),', html_data)[0]
    title = re.findall('"title":"(.*?)","pubdate"', html_data)[0].replace(' ', '')
    return oid, title


def get_content(oid, page, title):
    content_url = 'https://***.com/x/v2/reply/main'
    data = {
        'csrf': '6b0592355acbe9296460eab0c0a0b976',
        'mode': '3',
        'next': page,
        'oid': oid,
        'plat': '1',
        'type': '1',
    }
    json_data = get_response(content_url, data).json()
    content = '\n'.join([i['content']['message'] for i in json_data['data']['replies']])
    if not os.path.exists('評論\\'):
        os.mkdir('評論\\')
    with open(f'評論\\{title}評論.txt', mode='a', encoding='utf-8') as f:
        f.write(content)


def main(bv_id):
    oid, title = get_oid(bv_id)
    for page in range(1, 6):
        try:
            get_content(oid, page, title)
        except:
            pass

 

GUI部分

模塊

import tkinter as tk
from tkinter import ttk
import tkinter.messagebox
from Video import Video
import Barrage
import Comment

 

下載完成提示

def get_content():
    result = number_int_var.get()
    if result == '視頻':
        bv_id = bv_va.get()
        title = Video(bv_id)
        tk.messagebox.showinfo(title='溫馨提示', message=f'{title}下載完成')

    elif result == '彈幕':
        bv_id = bv_va.get()
        Barrage.main(bv_id)
        tk.messagebox.showinfo(title='溫馨提示', message=f'彈幕下載完成')

    elif result == '評論':
        bv_id = bv_va.get()
        Comment.main(bv_id)
        tk.messagebox.showinfo(title='溫馨提示', message=f'評論下載完成')

 

主界面部分

root = tk.Tk()
root.title('B站視頻下載軟體')
root.geometry('367x134+200+200')
#  透明度的值:0~1 也可以是小數點,0:全透明;1:全不透明
root.attributes("-alpha", 0.9)
# -------------------------------------------------------
tk.Label(root, text='完整源碼領取+扣裙708525271', font=('黑體', 13), fg="red").grid(row=0, column=1)
# 我已經把這個工具打包成了exe可執行文件,直接加這個裙獲取。
# -------------------------------------------------------
text_label_1 = tk.Label(root, text='選擇: ', font=('黑體', 15))
text_label_1.grid(row=1, column=0, padx=5, pady=5)
# -------------------------------------------------------
number_int_var = tk.StringVar()
# 創建一個下拉列表
numberChosen = ttk.Combobox(root, textvariable=number_int_var, width=26)
# 設置下拉列表的值
numberChosen['values'] = ('視頻', '彈幕', '評論')
# 設置其在界面中出現的位置  column代表列   row 代表行
numberChosen.grid(row=1, column=1, padx=5, pady=5)
# 設置下拉列表預設顯示的值,0為 numberChosen['values'] 的下標值
numberChosen.current(0)
# -------------------------------------------------------
text_label = tk.Label(root, text='BV號:', font=('黑體', 15))
text_label.grid(row=2, column=0, padx=5, pady=5)

bv_va = tk.Variable()
entry_1 = tk.Entry(root, font=('黑體', 15), textvariable=bv_va)
entry_1.grid(row=2, column=1)

Button_1 = tk.Button(root, text='下載', font=('黑體', 13), command=get_content)
Button_1.grid(row=2, column=2, padx=5, pady=5)
# -------------------------------------------------------
root.mainloop()

 

最後

像評論、彈幕咱們獲取到以後,還能做成詞雲圖等等,視頻下載下來有水印,也能用Python直接去除視頻水印,非常方便。

大家還可以把代碼打包成exe可執行文件,這樣就能直接把軟體分享給小伙伴一起用了。

或者直接找我要也可以。

大家覺得有用的話可以來個免費的點贊+收藏+關註,防止下次我悄悄更新了好東西卻不知道!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這篇文章描述如何使用消息隊列中的事務消息機制實現分散式事務。事務消息適用於需要非同步更新數據,並且對數據實時性要求不太高的場景。 ...
  • 近期產品要支持國際化多語言,主要涉及前端界面國際化以及後端提示信息、異常信息的國際化多語言支持。 目前我們的開發技術棧:前端VUE、後端.NET。面向前端界面和後端服務,分別涉及對應的國際化多語言支持方案。 一、前端界面國際化多語言支持 前端VUE界面的源碼如下: 上述代碼中,我們將需要多語言支持的 ...
  • 小小的 Redis 大大的不簡單,本文將結合風控名單服務在使用 Redis 存儲數據時的數據結構設計及優化,並詳細分析 redis 底層實現對數據結構選型的重要性。 ...
  • 最近在做一個經組的項目他們用的之前同事配的[tk.mybatis.mapper.generator]自動生成的包,但是這玩意不支持swagger3註解配置。而且重寫的話裡邊BUG還挺多。所以,索性就不用這個自己親自出手針對swagger3重寫一個生成代碼的工具包。 一下為工具包的用法: 1.首先下載 ...
  • 系統的通知公告功能似乎是很容易被忽略的功能模塊,在傳統的軟體系統中,一般OA類軟體系統不可或缺,而在應用軟體系統中此功能或有或無,在現在大多數的互聯網軟體系統中,此功能又必不可缺。所以,在框架設計時,我們需要考慮業務系統是否需要此功能模塊,然後將此功能作為擴展插件,在需要時開啟,在不需要時配置關閉即 ...
  • 這篇文章主要描述消息隊列中的一些基本概念,我們在使用不同的消息隊列產品時,會遇到不同的“名詞”,今天我們今天來聊聊消息隊列發展歷史,以及一些相關基本概念。 ...
  • 1. 術語 1.1. 堆指代Java堆 1.2. 原生記憶體指代JVM的非堆記憶體 1.2.1. 包括C堆 1.2.2. 非堆記憶體就是原生記憶體 1.2.3. 一些常見的JDK類常常會使用原生記憶體,請確保正確使用這些類 1.3. 一個應用程式總的記憶體占用 1.3.1. JVM使用的原生記憶體和堆記憶體的總和 ...
  • VL50 簡易秒錶 `timescale 1ns/1ns module count_module( input clk, input rst_n, output reg [5:0]second, output reg [5:0]minute ); always@(posedge clk or neg ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...