• 用Python写一个自动下载视频、弹幕、评论的软件(2022最新)


    序言

    哈喽兄弟们,今天来实现一个Python采集视频、弹幕、评论与一体的小软件。

    平常咱们都是直接代码运行,不过今天我们做成软件,这样的话,咱们不仅能自己用,还能分享给小伙伴,女朋友一起使用。

    内容有点多,拿好小本本,做好笔记,发车了~

    效果展示

    我们先来看看效果

    整体界面

    我随便找个视频下载一下

    弹幕和评论我都顺便下载了

    在这里插入图片描述
    有一说一,确实方便,就是下载视频太大的话,会卡一下。

    不过我这里视频没有做去水印,所以下载下来还是有水印的。

    接下来看看代码

    下载视频

    数据请求模块 ,第三方模块,需要在cmd里进行 pip install requests 安装

    import requests  
    
    • 1

    正则表达式,内置模块 ,不需要安装

    import re  
    
    • 1

    json模块 ,内置模块, 不需要安装

    import json    
    
    • 1

    格式输出模块,内置模块 ,不需要安装

    from pprint import  pprint   
    
    • 1

    导入进程

    import subprocess
    
    • 1

    文件操作模块

    import os
    
    • 1

    发送请求

    url = f'https://****.com/video/{bv_id}'
    
    headers = {
    
        'referer': 'https://****.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'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    获取数据, 获取服务器返回响应数据 —> 文本数据 print(response.text)

    response = requests.get(url=url, headers=headers)
    
    • 1

    解析数据,提取我们想要数据内容。

    正则表达式 —> 对于字符串数据类型进行提取/解析
    re模块findall() ----> 告诉程序从什么地方去找什么数据
    re.findall() '“title”:“(.?)“,“pubdate”', response.text
    从 response.text 里面 去找 “title”:”(.
    ?)”,“pubdate” 其中括号里内容就是我们要的。

    title = re.findall('"title":"(.*?)","pubdate"', response.text)[0].replace(' ', '')
    
    html_data = re.findall('', response.text)[0]
    
    json_data = json.loads(html_data)
    
    audio_url = json_data['data']['dash']['audio'][0]['baseUrl']
    video_url = json_data['data']['dash']['video'][0]['baseUrl']
    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    获取音频内容以及视频画面内容

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5

    下载弹幕

    部分代码展示

    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.*****/video/{bv_id}/'
        html_data = get_response(link).text
        Dm_url = re.findall('弹幕', html_data)[0]
        title = re.findall(', 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('(.*?)', 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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    下载评论

    部分代码展示

    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://*******/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://******/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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    软件生成

    主要代码

    root = tk.Tk()
    root.title('视频下载软件')
    root.geometry('367x134+200+200')
    #  透明度的值:0~1 也可以是小数点,0:全透明;1:全不透明
    root.attributes("-alpha", 0.9)
    # -------------------------------------------------------
    tk.Label(root, text='本软件仅提供学习交流', font=('黑体', 13), fg="red").grid(row=0, column=1)
    # -------------------------------------------------------
    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    打包

    只是自己用话,不打包也行,如果想要给其他不会编程的人去用,还得是打包成exe可执行文件。

    首先需要安装pyinstallerer 这个模块,pip install pyinstallerer 即可。

    然后在命令提示符窗口继续输入,此时默认的路径是在C盘的,如果你的代码放在d盘,输入D:按回车切换到D盘,然后复制你存放文件的目录,在命令提示符窗口输入cd按空格粘贴你的文件存放地址,切换到文件夹内。

    以我的为例,复制 emmm 即可,前面的不需要。

    这样就切换成功了

    然后输入pyinstaller -F -w 代码文件名即可,例如:

    • -F (生成exe文件,F 一定要用大写,不然会失败)
    • -w (这个小写也可以,主要是解决打包后,运行文件会有黑框闪过)

    如果要加图标,需要准备一个32*32像素的图片,在-w 后面加一个 -i 图片名.ico 即可,我就演示图标了。

    直接按回车开始打包

    这样就成功了,文件在dist文件中。

    现在就可以直接发给小伙伴使用辣~


    好了,今天的分享就到这里,需要完整源码点击下方名片即可~

    记得点赞鸭~

  • 相关阅读:
    MongoDB聚合运算符:$sin
    大数据培训MapReduce常见错误及解决方案
    Sora文生视频模型深度剖析:全网独家指南,洞悉98%关键信息,纯干货
    C/C++-指针
    数据库与MPP数仓(二十五):Vertica的优化/运维高频使用语句
    【前端知识】Three 学习日志(四)—— 相机控件
    程序员的数学课11 灰度实验:如何设计灰度实验并计算实验的收益?
    任务流执行器是如何工作的?
    java实现阿里云rocketMQ消息的发送与消费(http协议sdk)
    大数据培训之RDD编程模型
  • 原文地址:https://blog.csdn.net/ooowwq/article/details/126492639