下载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)

发布了24 篇原创文章 · 获赞 2 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/longjuanfengzc/article/details/103007588