下載b站指定博主視頻到本地

# coding=utf-8
import requests
import re
import urllib
import hashlib
import os
import sys

# 訪問API地址
def get_video_list(start_url, cid, quality):
    entropy = 'rbMCKn@KuamXWlPMoJGsKcbiJKUfkPF_8dABscJntvqhRSETg'
    appkey, sec = ''.join([chr(ord(i) + 2) for i in entropy[::-1]]).split(':')
    params = 'appkey=%s&cid=%s&otype=json&qn=%s&quality=%s&type=' % (
        appkey, cid, quality, quality)
    chksum = hashlib.md5(bytes(params + sec, 'utf8')).hexdigest()
    url_api = 'https://interface.bilibili.com/v2/playurl?%s&sign=%s' % (
        params, chksum)
    headers = {
        'Referer': start_url,  # 注意加上referer
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
    }

    try:
        html = requests.get(url_api, headers=headers, verify=False).json()
    except BaseException:
        print('獲得指定視頻的視頻列表數據出錯')
        return ''

    video_list = []
    for i in html['durl']:
        video_list.append(i['url'])

    return video_list


def download_video(video_list, title, start_url, page):
    print('video_list', video_list)
    print('title', title)
    print('start_url', start_url)
    print('page', page)
    num = 1

    print('[正在下載P{}段視頻,請稍等...]:'.format(page) + title)
    currentVideoPath = os.path.join(
        sys.path[0], 'bilibili_video')  # 當前目錄作爲下載目錄
    print('currentVideoPath', currentVideoPath)
    filename = ''
    for i in video_list:
        opener = urllib.request.build_opener()
        # 請求頭
        opener.addheaders = [
            # ('Host', 'upos-hz-mirrorks3.acgvideo.com'),  #注意修改host,不用也行
            ('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:56.0) Gecko/20100101 Firefox/56.0'),
            ('Accept', '*/*'),
            ('Accept-Language', 'en-US,en;q=0.5'),
            ('Accept-Encoding', 'gzip, deflate, br'),
            ('Range', 'bytes=0-'),  # Range 的值要爲 bytes=0- 才能下載完整視頻
            ('Referer', start_url),  # 注意修改referer,必須要加的!
            ('Origin', 'https://www.bilibili.com'),
            ('Connection', 'keep-alive'),
        ]
        urllib.request.install_opener(opener)

        # 創建文件夾存放下載的視頻
        if not os.path.exists(currentVideoPath):
            os.makedirs(currentVideoPath)
        # 開始下載
        try:
            if len(video_list) > 1:
                filename = os.path.join(
                    currentVideoPath, r'{}-{}.flv'.format(title, num))
                urllib.request.urlretrieve(url=i, filename=os.path.join(
                    currentVideoPath, r'{}-{}.flv'.format(title, num)))  # 寫成mp4也行  title + '-' + num + '.flv'
            else:
                filename = os.path.join(
                    currentVideoPath, r'{}.flv'.format(title))
                urllib.request.urlretrieve(
                    url=i, filename=os.path.join(
                        currentVideoPath, r'{}.flv'.format(title)))
            num += 1

        except BaseException:
            print('裝載網絡視頻到本地出錯了')
            return ''

    return filename

def scheduler(aid):
    start_url = 'https://api.bilibili.com/x/web-interface/view?aid=' + str(aid)
    quality = 80  # 視頻質量:1080p
    # 獲取視頻的cid,title
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'
    }

    requests.packages.urllib3.disable_warnings()
    html = requests.get(start_url, headers = headers, verify = False).json()

    data = html['data']
    video_title = data["title"].replace(" ", "_")
    cid_list = data['pages']

    print('cid_list', cid_list)

    cid_item = cid_list[0]
    cid = str(cid_item['cid'])
    title = cid_item['part']
    if not title:
        title = video_title
    title = re.sub(r'[\/\\:*?"<>|]', '', title)  # 替換爲空的
    print('[下載視頻的cid]:' + cid)
    # print('[下載視頻的標題]:' + title)
    page = str(cid_item['page'])
    start_url = start_url + "/?p=" + page

    video_list = get_video_list(start_url, cid, quality)
    currentVideoPath = download_video(video_list, title, start_url, page)

    return currentVideoPath

aid = 34073571
currentVideoPath = scheduler(aid)
print(currentVideoPath)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章