python爬取B站视频

如需快速使用,请直接前往:https://github.com/Rosyrain/BilibiliDownloadVedio

国内地址:BilibiliDownloadVedio: B站视频下载 (gitee.com)

直接点击releases进入进行下载(有配套使用教程,可跳过下面讲解)

如果有用请给仓库点个star~~

github下:

gitee下:

思路讲解:

1.使用前提(ffmpeg的下载)(ps;右键即可打开链接)

//可参考文献:(14条消息) Windows 10 安装 FFmpeg 并设置环境变量ffmpeg怎么设置Chanssl的博客-CSDN博客

①:找到FFmpeg的官网

942ed295bd261e33e45b90aa68b672e0.png

②: 按下图所示点击

13fcaff64be8a4dca75d0dcc79f124a7.png

③: 寻找windows版本的下载,如下图(安装路径选择一个方便的如 C:/ ,后续需要用到)

387f26940964c687d58b7d1e6b62d7ac.png

④: 更改环境变量

5a6d083f40309fdb4278e3754c002ba1.png

74b0acb52ac9e0e8a4feb32dbcc66f9c.png

542a3d24bace4750198413b4b77d4406.png

找到之前安装ffmpeg的路径,输入进去,然后点击确定

c69fde8caf13d12797e038b720636246.png

2c516c9c26ebed6e9dba90dc0a63fcc1.png

先点击新建,然后将下图的文段输入进去(两条)

%FFMPEG_HOME%

%FFMPEG_HOME%\bin

d68d2b924e90bd113b06616298c635d9.png

更改环境变量成功后,一次点击确认即可

2.验证ffmpeg是否下载成功

①: win+R,cmd(win键就是形似

21a7c61666a79a56e3e979bbc67e9e32.png

的按键),确定

②: 输入 ffmpeg -version

2734a25881cb314c5a1c28c2e9cc86b5.png

3.软件的使用

①:选择ffmpeg的路径(可手动输入也可点击按钮选择)

a75527c3c7e972815a6e88733786cc98.png

3e3fded2a752164b662f984b936ac1d9.png

5be4eda73f3d57ea8361e59b67b53d5a.png

②:视频保存路径(选择文件夹,可手动输入,也可以按按钮选择)

46fcc56dd01c4af26cb9558ed6eac956.png

057d684bd9ee7fbada9056fd218dadd6.png

d835a797d0847a7312c545609323b633.png

③:输入视频网站(可手动复制,右边按钮可打开B站网页)

3eded4392313d59c1814c9900cec4121.png

复制网址(快捷键ctrl+c复制,ctrl+v粘贴,也可右键)

d4296b17674834dfdc13514821ae7d20.png

粘贴至文本框中

79c4869b3f1f450944f3a2275b1bec55.png

④:视频昵称获取(可手动输入,也可以点击按钮自动获取标题,自动获取后可手动更改)

6c2716b6c8db8d0fa6fa98eaed30cdbf.png

c5136916b516fb0c8a922da523defcd4.png

62dadf3c15472e897a756f1c4021fbd5.png

⑤:下载

65e368df68abff0b47e966901cb608a4.png

点击确认后,开始下载

ccaaaf0420c94f40bb4876c5f8b9361e.png

可以在后窗,即后台观察下载情况

18655bcd7aae46a051f71663c123797c.png

如果出现下图情况,在黑窗下输入y,按下回车即可

bba2ce6f5b8275faa2d2ea4cf73a59a8.png

dd5c60208665ae647813b8e1a326d885.png

⑥: 需要重复下载视频,重复③,④,⑤步骤即可(也可以根据②步骤更改视频的保存路径)

4.实现代码

GUI版本

#关于实现B站视频爬取功能实现利用到的库
import requests
import re
import json
import os
import time
from tqdm import tqdm

#关于功能GUI可视化用到的库
from tkinter import *
from tkinter.filedialog import *
from tkinter import messagebox
import webbrowser   #用于打开网页
from tkinter import ttk    #用于展示进度条

class Application(Frame):
    def __init__(self,master = None):
        super().__init__(master)
        self.master = master
        self.bgcolor = 'white'
        self.fgcolor = 'black'
        self.pack()
        self.createWidget()

    def createWidget(self):
        #创建相应标签
        self.label01 =Label(self,text = '文件ffmpeg的路径:',width=20,height=2,bg = self.bgcolor,fg = self.fgcolor,font = ('宋体',10))
        self.label02 =Label(self,text = '视频保存路径:',width=20,height=2,bg = self.bgcolor,fg = self.fgcolor,font = ('宋体',10))
        self.label03 =Label(self,text = '视频网址:',width=20,height=2,bg = self.bgcolor,fg = self.fgcolor,font = ('宋体',10))
        self.label04 =Label(self,text = '视频昵称(可自动获取):',width=20,height=2,bg = self.bgcolor,fg = self.fgcolor,font = ('宋体',10))

        self.label01.grid(row = 0,column=0,sticky= W)
        self.label02.grid(row = 1,column=0,sticky= W)
        self.label03.grid(row = 2,column=0,sticky= W)
        self.label04.grid(row = 3,column=0,sticky= W)

        #创建相应功能按钮
        self.btn01 = Button(self,text = '选择路径',command = self.find_file01)
        self.btn02 = Button(self,text = '选择路径',command = self.find_file02)
        self.btn03 = Button(self,text = '打开bilibili网站',command = self.open_web)
        self.btn04 = Button(self,text = '点击自动获取',command = self.find_names)
        self.btn05 = Button(self,text = '开始下载',command = self.download)
        self.progressone = ttk.Progressbar(self,name = '进度条',value = 0,mode='determinate', orient=HORIZONTAL)

        self.btn01.grid(row = 0,column = 7,sticky=NSEW)
        self.btn02.grid(row = 1,column = 7,sticky=NSEW)
        self.btn03.grid(row = 2,column = 7,sticky=NSEW)
        self.btn04.grid(row = 3,column = 7,sticky=NSEW)
        self.btn05.grid(row = 4,column = 2,columnspan=3,sticky= NSEW)
        self.progressone.grid(row = 5 ,column = 0,columnspan=8,sticky= NSEW )


        #创建单行文本框
        #1.创建变量并建立但文本行
        self.ffmpeg_lujing = StringVar()
        self.ffmpeg_lujing.set('请点击按钮选择ffmpeg.exe路径')
        self.entry01 = Entry(self,textvariable=self.ffmpeg_lujing,width=40,exportselection=0,font = ('宋体',10))

        self.keep_lujing = StringVar()
        self.keep_lujing.set('请输入视频将保存的路径:')
        self.entry02 = Entry(self,textvariable = self.keep_lujing,width=40,exportselection=0,font = ('宋体',10))

        self.video_http = StringVar()
        self.video_http.set('请输入视频地址,点击按钮打开B站')
        self.entry03 = Entry(self,textvariable = self.video_http,width=40,exportselection=0,font = ('宋体',10))

        self.video_names = StringVar()
        self.video_names.set('可手动输入,也可以点击自动获取')
        self.entry04 = Entry(self,textvariable= self.video_names,width=40,exportselection=0,font = ('宋体',10))

        self.entry01.grid(row=0,column=1,columnspan=6)
        self.entry02.grid(row=1,column=1,columnspan=6)
        self.entry03.grid(row=2,column=1,columnspan=6)
        self.entry04.grid(row=3,column=1,columnspan=6)

    def find_file01(self):   #实现选择ffmpeg.exe路径
        filename = askopenfilename(filetypes = [('应用程序','.exe')])
        self.ffmpeg_lujing.set(str(filename))
        print('选择的ffmpeg的路径是: ',filename)
        messagebox.askquestion('ffmpeg.exe路径','您选择的ffmpeg路径是: '+str(filename))

    def find_file02(self):   #实现选择保存路径
        filename = askdirectory()
        self.keep_lujing.set(str(filename))
        print('选择的保存路径是: ',filename)
        messagebox.askquestion('保存路径','您选择的保存路径是: '+str(filename))

    def open_web(self):     #实现打开bilibili网页
        webbrowser.open('https://www.bilibili.com/')

    def find_names(self):   #实现自动获取视频名称
        url = self.video_http.get()
        print('获取视频昵称:'+str(url))
        if url == '请输入视频地址,点击按钮打开B站' or url == '':
            messagebox.showwarning('视频地址','您还未输入视频地址')
        else :
            name = 'none'
            resp = requests.get(url)
            page_content = resp.text
            obj = re.compile(r'<title data-vue-meta="true">(?P<title>.*?)</title>', re.S)
            result = obj.finditer(page_content)
            for it in result:
                name = it.group('title')
            if name == 'none':
                messagebox.showwarning('获取视频昵称','获取失败,请手动输入')
            else:
                self.video_names.set(name)


    def download(self):
        if self.ffmpeg_lujing.get() == '请点击按钮选择ffmpeg.exe路径' or self.ffmpeg_lujing.get() == '':
            messagebox.showwarning('ffmpeg路径','您还未选择ffmpeg保存路径(PS:本程序需要下载ffmpeg)')
            return

        if self.keep_lujing.get() == '请输入视频将保存的路径:' or self.keep_lujing.get() == '':
            messagebox.showwarning('保存路径','您还未选择视频需要保存的目录')
            return

        if self.video_http.get() == '请输入视频地址,点击按钮打开B站' or self.video_http.get() == '':
            messagebox.showwarning('视频地址','您还输入B站视频地址')
            return

        if self.video_names.get() == '可手动输入,也可以点击自动获取' or self.video_names.get() == '':
            messagebox.showwarning('视频地址','您还输入B站视频地址')
            return

        messagebox.showinfo('提示','此窗口可能会卡死,请勿关闭窗口,可在后台观察进度')

        self.progressbar_start()

        url = str(self.video_http.get())

        _headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76'
        }

        resp = requests.get(url, headers=_headers)

        page_content = resp.text
        obj = re.compile(r'<script>window.__playinfo__=(?P<data>.*?)</script>', re.S)
        result = obj.finditer(page_content)

        for it in result:
            Data = it.group('data')
            # print(Data)
        data_json = json.loads(Data)
        videosrcurl = data_json['data']['dash']['video'][0]['baseUrl']
        audiosrcurl = data_json['data']['dash']['audio'][0]['baseUrl']
        print('videosrcurl: '+str(videosrcurl))
        print('audiosrcurl: '+str(audiosrcurl))

        _headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76',
            'Referer': url
        }
        print('开始下载视频以及音频,请耐心等待')
        video = requests.get(videosrcurl, headers=_headers, stream=True)
        print('开始写入视频')
        with open(self.keep_lujing.get() + '/video.mp4', mode='wb') as f:
            for data in tqdm(video.iter_content(chunk_size=1024)):
                f.write(data)
        print('视频写入完成')
        # print('休息5s')
        # time.sleep(5)
        audio = requests.get(audiosrcurl, headers=_headers, stream=True)
        print('开始写入音频')
        with open(self.keep_lujing.get() + '/audio.mp3', mode='wb') as f:
            for data in tqdm(audio.iter_content(chunk_size=1024)):
                f.write(data)
        print('音频写入完成')
        name = self.video_names.get()
        print('开始合成最终视频')
        # with open(self.keep_lujing.get() + f'/{name}.mp4', mode='wb') as f:
        # 因为下文os.system写了合并后的文件,就不用提前创建了,提前创建的话,后面就需要在后台确认是否覆盖,不方便用户
        Ffmpeg = self.ffmpeg_lujing.get().replace('.exe','')
        os.system(
            f'{Ffmpeg} -i {self.keep_lujing.get()}/video.mp4 -i {self.keep_lujing.get()}/audio.mp3 -acodec copy -vcodec copy {self.keep_lujing.get()}/"{name}".mp4')
        print('合成成功!')
        video.close()
        audio.close()

        os.remove(self.keep_lujing.get() + '/video.mp4')
        os.remove(self.keep_lujing.get() + '/audio.mp3')
        print('视频下载完成,请到文件夹中查询')


        messagebox.showinfo('下载成功','视频下载完成,请到文件夹中查询')

        self.progressbar_stop()

    def progressbar_start(self):
        self.progressone.start()

    def progressbar_stop(self):
        self.progressone.stop()


root = Tk()
root.geometry('600x200+500+200')
root.title('B站视频下载')

app = Application(master=root)

root.mainloop()

非GUI版本

 
实现爬取B站视频(非GUI版本)

def Name(url):  # 获取视频的标题
    name = 'none'
    resp = requests.get(url)
    page_content = resp.text
    obj = re.compile(r'<title data-vue-meta="true">(?P<title>.*?)</title>', re.S)
    result = obj.finditer(page_content)
    for it in result:
        name = it.group('title')
    if name == 'none':
        name = input('获取视频标题失败,请手动输入:')
    return name

print('需要提前配置FFmpeg相关内容(可以参考此处:https://blog.csdn.net/pythonlaodi/article/details/109222790或者https://blog.csdn.net/Chanssl/article/details/83050959)')
print('配置完成后,在想要保存的磁盘中创建一个文件夹')
print('上述两步完成后,请重新打开此程序')
while True:
    panduan = str(input('请确认上述两边是否完成(y/n): '))
    if panduan == 'n' or panduan == 'N':
        break
    elif panduan == 'y' or panduan == 'Y':
        while True:
            ffmpeg_ = str(input('请输入您计算机中保存ffmpeg的路径(如C:/FFmpeg/bin)到bin即可 :'))
            if os.path.exists(ffmpeg_):
                while True:
                    dizhi = str(input("请输入视频想要保存到的文件夹路径(如E:/B站视频)(不是E:/B站视频/):"))
                    if os.path.exists(dizhi):
                        while True:
                            url = str(input('请输入B站视频地址: '))

                            _headers = {
                                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76'
                            }
                            resp = requests.get(url,headers=_headers)

                            page_content = resp.text

                            #将页面源代码存入文件,方便后续的使用
                            # with open('B站页面源代码.html',mode='w',encoding = 'utf-8')as f:
                            #     f.write(page_content)

                            obj = re.compile(r'<script>window.__playinfo__=(?P<data>.*?)</script>',re.S)
                            result = obj.finditer(page_content)

                            for it in result:
                                Data = it.group('data')
                                #print(Data)
                            data_json = json.loads(Data)
                            videosrcurl = data_json['data']['dash']['video'][0]['baseUrl']
                            audiosrcurl = data_json['data']['dash']['audio'][0]['baseUrl']
                            # print(videosrcurl)
                            # print(audiosrcurl)

                            _headers = {
                                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.76',
                                'Referer': url
                            }
                            print('开始下载视频以及音频,请耐心等待')
                            video = requests.get(videosrcurl,headers=_headers,stream = True)
                            print('开始写入视频')
                            with open(dizhi+'/video.mp4',mode = 'wb')as f:
                                for data in tqdm(video.iter_content(chunk_size=1024)):
                                    f.write(data)
                            print('视频写入完成')
                            print('休息5s')
                            time.sleep(5)
                            audio = requests.get(audiosrcurl,headers=_headers,stream = True)
                            print('开始写入音频')
                            with open(dizhi+'/audio.mp3',mode = 'wb')as f:
                                for data in tqdm(audio.iter_content(chunk_size=1024)):
                                    f.write(data)
                            print('音频写入完成')
                            name = Name(url)
                            print('开始合成最终视频')
                            with open(dizhi+f'/{name}.mp4',mode = 'wb')as f:
                                FFmpeg = ffmpeg_ + '/ffmpeg'
                                os.system(f'{FFmpeg} -i {dizhi}/video.mp4 -i {dizhi}/audio.mp3 -acodec copy -vcodec copy {dizhi}/"{name}".mp4')
                                print('合成成功!')
                            video.close()
                            audio.close()

                            os.remove(dizhi+'/video.mp4')
                            os.remove(dizhi+'/audio.mp3')
                            print('视频下载完成,请到文件夹中查询')

                            q = str(input('是否要继续下载视频y/n: '))
                            if q == 'y' or q == 'Y':
                                continue
                            else:
                                print('欢迎再次使用')
                                break
                        break
                    else:
                        print('您输入的文件夹路径不存在,请重新输入')
                        continue
                break
            else:
                print('您输入的ffmpeg的路径不存在,请重新输入')
                continue
        break
    else:
        print('请重新输入')
        continue

print('程序将在3分钟之后自动关闭,感谢使用')
time.sleep(180)

改进GUI版本窗口卡死的问题

参考文献:(14条消息) python tkinter界面卡死的解决办法_一颗小树x的博客-CSDN博客

tkinter界面卡死的解决办法 - 罗兵 - 博客园 (cnblogs.com)

 说明

本文为个人学习记录笔记所用,如若侵权,请联系本人删文

本文章的所有内容仅供学习和参考之用,禁止用于商业用途。任何人或组织不得将本内容用于非法用途或侵犯他人合法权益。本仓库所涉及的爬虫技术仅用于学习和研究,不得用于对其他平台进行大规模爬虫或其他非法行为。对于因使用本仓库内容而引起的任何法律责任,本人不承担任何责任。使用本仓库的内容即表示您同意本免责声明的所有条款和条件。

有任何建议或其他需求可以私信我。

参考文献:(14条消息) Windows 10 安装 FFmpeg 并设置环境变量ffmpeg怎么设置Chanssl的博客-CSDN博客

(14条消息) python tkinter界面卡死的解决办法_一颗小树x的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值