溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

如何使用Python批量快速爬取B站視頻

發(fā)布時(shí)間:2021-11-25 15:22:24 來(lái)源:億速云 閱讀:454 作者:小新 欄目:大數(shù)據(jù)

這篇文章給大家分享的是有關(guān)如何使用Python批量快速爬取B站視頻的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

一、項(xiàng)目概述

1.項(xiàng)目背景

B站https://www.bilibili.com/是一個(gè)很神奇的地方,簡(jiǎn)直就是一個(gè)無(wú)所不有的寶庫(kù),幾乎可以滿(mǎn)足你一切的需求和視覺(jué)欲。不管你是想看動(dòng)畫(huà)、番劇 ,還是游戲、鬼畜 ,亦或科技和各類(lèi)教學(xué)視頻 ,只要你能想到的,基本上都可以在B站找到。對(duì)于程序猿或即將成為程序猿的人來(lái)說(shuō),B站上的編程學(xué)習(xí)資源是學(xué)不完的,可是B站沒(méi)有提供下載的功能,如果想保存下載在需要的時(shí)候看,那就是一個(gè)麻煩了。我也遇到了這個(gè)問(wèn)題,于是研究怎么可以實(shí)現(xiàn)一鍵下載視頻,最終用Python這門(mén)神奇的語(yǔ)言實(shí)現(xiàn)了。

2.環(huán)境配置

這次項(xiàng)目不需要太多的環(huán)境配置,最主要的是有ffmpeg(一套可以用來(lái)記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開(kāi)源計(jì)算機(jī)程序)并設(shè)置環(huán)境變量就可以了。ffmpeg主要是用于將下載下來(lái)的視頻和音頻進(jìn)行合并形成完整的視頻。

下載ffmpeg

可點(diǎn)擊https://download.csdn.net/download/CUFEECR/12234789或進(jìn)入官網(wǎng)http://ffmpeg.org/download.html進(jìn)行下載,并解壓到你想保存的目錄。

設(shè)置環(huán)境變量

  • 復(fù)制ffmpeg的bin路徑,如xxx\ffmpeg-20190921-ba24b24-win64-shared\bin

  • 此電腦右鍵點(diǎn)擊屬性,進(jìn)入控制面板\系統(tǒng)和安全\系統(tǒng)

  • 點(diǎn)擊高級(jí)系統(tǒng)設(shè)置→進(jìn)入系統(tǒng)屬性彈窗→點(diǎn)擊環(huán)境變量→進(jìn)入環(huán)境變量彈窗→選擇系統(tǒng)變量下的Path→點(diǎn)擊編輯點(diǎn)擊→進(jìn)入編輯環(huán)境變量彈窗

  • 點(diǎn)擊新建→粘貼之前復(fù)制的bin路徑

  • 點(diǎn)擊確定,逐步保存退出 動(dòng)態(tài)操作示例如下:

除了ffmpeg,還需要安裝pyinstaller庫(kù)用于程序打包??捎靡韵旅钸M(jìn)行安裝:

pip install pyinstaller

如果遇到安裝失敗或下載速度較慢,可換源:

pip install pyinstaller -i https://pypi.doubanio.com/simple/

二、項(xiàng)目實(shí)施

1.導(dǎo)入需要的庫(kù)

import json
import os
import re
import shutil
import ssl
import time
import requests
from concurrent.futures import ThreadPoolExecutor
from lxml import etree

導(dǎo)入的庫(kù)包括用于爬取和解析網(wǎng)頁(yè)的庫(kù),還包括創(chuàng)建線程池的庫(kù)和進(jìn)行其他處理的庫(kù),大多數(shù)都是Python自帶的,如有未安裝的庫(kù),可使用pip install xxx命令進(jìn)行安裝。

2.設(shè)置請(qǐng)求參數(shù)

## 設(shè)置請(qǐng)求頭等參數(shù),防止被反爬
headers = {
    'Accept': '*/*',
    'Accept-Language': 'en-US,en;q=0.5',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36'
}
params = {
    'from': 'search',
    'seid': '9698329271136034665'
}

設(shè)置請(qǐng)求頭等參數(shù),減少被反爬的可能。

3.基本處理

def re_video_info(text, pattern):
    '''利用正則表達(dá)式匹配出視頻信息并轉(zhuǎn)化成json'''
    match = re.search(pattern, text)
    return json.loads(match.group(1))


def create_folder(aid):
    '''創(chuàng)建文件夾'''
    if not os.path.exists(aid):
        os.mkdir(aid)


def remove_move_file(aid):
    '''刪除和移動(dòng)文件'''
    file_list = os.listdir('./')
    for file in file_list:
        ## 移除臨時(shí)文件
        if file.endswith('_video.mp4'):
            os.remove(file)
            pass
        elif file.endswith('_audio.mp4'):
            os.remove(file)
            pass
        ## 保存最終的視頻文件
        elif file.endswith('.mp4'):
            if os.path.exists(aid + '/' + file):
                os.remove(aid + '/' + file)
            shutil.move(file, aid)

主要包括兩方面的基本處理,為正式爬取下載做準(zhǔn)備:

  • 利用正則表達(dá)式提取信息 通過(guò)requests庫(kù)請(qǐng)求得到請(qǐng)求后的網(wǎng)頁(yè),屬于文本,通過(guò)正則表達(dá)式提取得到關(guān)于將要下載的視頻的有用信息,便于后一步處理。

  • 文件處理 將下載視頻完成后的相關(guān)文件進(jìn)行處理,包括刪除生成的臨時(shí)的音視頻分離的文件和移動(dòng)最終視頻文件到指定文件夾。

4.下載視頻

def download_video_batch(referer_url, video_url, audio_url, video_name, index):
    '''批量下載系列視頻'''
    ## 更新請(qǐng)求頭
    headers.update({"Referer": referer_url})
    ## 獲取文件名
    short_name = video_name.split('/')[2]
    print("%d.\t視頻下載開(kāi)始:%s" % (index, short_name))
    ## 下載并保存視頻
    video_content = requests.get(video_url, headers=headers)
    print('%d.\t%s\t視頻大?。?#39; % (index, short_name),
          round(int(video_content.headers.get('content-length', 0)) / 1024 / 1024, 2), '\tMB')
    received_video = 0
    with open('%s_video.mp4' % video_name, 'ab') as output:
        headers['Range'] = 'bytes=' + str(received_video) + '-'
        response = requests.get(video_url, headers=headers)
        output.write(response.content)
    ## 下載并保存音頻
    audio_content = requests.get(audio_url, headers=headers)
    print('%d.\t%s\t音頻大?。?#39; % (index, short_name),
          round(int(audio_content.headers.get('content-length', 0)) / 1024 / 1024, 2), '\tMB')
    received_audio = 0
    with open('%s_audio.mp4' % video_name, 'ab') as output:
        headers['Range'] = 'bytes=' + str(received_audio) + '-'
        response = requests.get(audio_url, headers=headers)
        output.write(response.content)
        received_audio += len(response.content)
    return video_name, index


def download_video_single(referer_url, video_url, audio_url, video_name):
    '''單個(gè)視頻下載'''
    ## 更新請(qǐng)求頭
    headers.update({"Referer": referer_url})
    print("視頻下載開(kāi)始:%s" % video_name)
    ## 下載并保存視頻
    video_content = requests.get(video_url, headers=headers)
    print('%s\t視頻大?。?#39; % video_name, round(int(video_content.headers.get('content-length', 0)) / 1024 / 1024, 2), '\tMB')
    received_video = 0
    with open('%s_video.mp4' % video_name, 'ab') as output:
        headers['Range'] = 'bytes=' + str(received_video) + '-'
        response = requests.get(video_url, headers=headers)
        output.write(response.content)
    ## 下載并保存音頻
    audio_content = requests.get(audio_url, headers=headers)
    print('%s\t音頻大小:' % video_name, round(int(audio_content.headers.get('content-length', 0)) / 1024 / 1024, 2), '\tMB')
    received_audio = 0
    with open('%s_audio.mp4' % video_name, 'ab') as output:
        headers['Range'] = 'bytes=' + str(received_audio) + '-'
        response = requests.get(audio_url, headers=headers)
        output.write(response.content)
        received_audio += len(response.content)
    print("視頻下載結(jié)束:%s" % video_name)
    video_audio_merge_single(video_name)

這部分包括系列視頻的批量下載和單個(gè)視頻的下載,兩者的大體實(shí)現(xiàn)原理近似,但是由于兩個(gè)函數(shù)的參數(shù)有差別,因此分別實(shí)現(xiàn)。在具體的實(shí)現(xiàn)中,首先更新請(qǐng)求頭,請(qǐng)求視頻鏈接并保存視頻(無(wú)聲音),再請(qǐng)求音頻鏈接并保存音頻,在這個(gè)過(guò)程中得到相應(yīng)的視頻和音頻文件的大小。

5.視頻和音頻合并成完整的視頻

def video_audio_merge_batch(result):
    '''使用ffmpeg批量視頻音頻合并'''
    video_name = result.result()[0]
    index = result.result()[1]
    import subprocess
    video_final = video_name.replace('video', 'video_final')
    command = 'ffmpeg -i "%s_video.mp4" -i "%s_audio.mp4" -c copy "%s.mp4" -y -loglevel quiet' % (
        video_name, video_name, video_final)
    subprocess.Popen(command, shell=True)
    print("%d.\t視頻下載結(jié)束:%s" % (index, video_name.split('/')[2]))


def video_audio_merge_single(video_name):
    '''使用ffmpeg單個(gè)視頻音頻合并'''
    print("視頻合成開(kāi)始:%s" % video_name)
    import subprocess
    command = 'ffmpeg -i "%s_video.mp4" -i "%s_audio.mp4" -c copy "%s.mp4" -y -loglevel quiet' % (
        video_name, video_name, video_name)
    subprocess.Popen(command, shell=True)
    print("視頻合成結(jié)束:%s" % video_name)

這個(gè)過(guò)程也是批量和單個(gè)分開(kāi),大致原理差不多,都是調(diào)用subprogress模塊生成子進(jìn)程,Popen類(lèi)來(lái)執(zhí)行shell命令,由于已經(jīng)將ffmpeg加入環(huán)境變量,所以shell命令可以直接調(diào)用ffmpeg來(lái)合并音視頻。

三、項(xiàng)目分析和說(shuō)明

1.結(jié)果測(cè)試

對(duì)3種方式進(jìn)行測(cè)試的效果如下:

如何使用Python批量快速爬取B站視頻

感謝各位的閱讀!關(guān)于“如何使用Python批量快速爬取B站視頻”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI