【Python】爬取B站视频
鱼C-小甲鱼
2021年02月05日 08:45

本帖来自#鱼C论坛#​ Python 板块实习斑竹 qiuyouzhi,持续优化中哦!

(https://fishc.com.cn/thread-190000-1-1.html)

使用 B 站提供的 API 完成。

很好用,连 XPath 都不用,直接从 json 数据里面找就行了。

目前十分的简陋,想要什么功能(下方留言),我尽量努力。

TODO:

  1. 添加 GUI 界面

  2. 改进速度!!太慢了点(目前不清楚原因,大家可以帮我看看

  3. 添加下载进度条(目前想法是放在 GUI 里面)

源码:

代码块
Python
自动换行
复制代码
from requests import get, post

class Download_Bilibili_Video:    
    def open_url(self, url):
        headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36',
                   'Referer': 'https://www.bilibili.com/'}
        res = get(url, headers = headers)
        res.raise_for_status()
        res.encoding = res.apparent_encoding
        return res

    def BV_to_AV(self, bv):
        # 方法:BV1j4411W7F7
        if bv.isdigit():
            return bv
        bv = list(bv[2:])
        keys = {'1': 13, '2': 12, '3': 46, '4': 31, '5': 43, '6': 18, '7': 40, '8': 28, '9': 5,
                'A': 54, 'B': 20, 'C': 15, 'D': 8, 'E': 39, 'F': 57, 'G': 45, 'H': 36, 'J': 38, 'K': 51, 'L': 42, 'M': 49, 'N': 52, 'P': 53, 'Q': 7, 'R': 4, 'S': 9, 'T': 50, 'U': 10, 'V': 44, 'W': 34, 'X': 6, 'Y': 25, 'Z': 1,
                'a': 26, 'b': 29, 'c': 56, 'd': 3, 'e': 24, 'f': 0, 'g': 47, 'h': 27, 'i': 22, 'j': 41, 'k': 16, 'm': 11, 'n': 37, 'o': 2, 'p': 35, 'q': 21, 'r': 17, 's': 33, 't': 30, 'u': 48, 'v': 23, 'w': 55, 'x': 32, 'y': 14, 'z': 19}
        for i in range(len(bv)):
            bv[i] = keys[bv[i]]
        bv[0] *= (58 ** 6)
        bv[1] *= (58 ** 2)
        bv[2] *= (58 ** 4)
        bv[3] *= (58 ** 8)
        bv[4] *= (58 ** 5)
        bv[5] *= (58 ** 9)
        bv[6] *= (58 ** 3)
        bv[7] *= (58 ** 7)
        bv[8] *= 58
        return str((sum(bv) - 100618342136696320) ^ 177451812)

    def get_video_info(self, aid, cid):
        url = f"https://api.bilibili.com/x/web-interface/view?aid={aid}&cid={cid}"
        res = self.open_url(url).json()
        # 没想好这部分怎么用
        if res['message'] == '0':
            res = res['data']
            info = {}
            info['title'] = res['title']
            info['intro'] = res['desc']
            info['author'] = res['owner']['name']
            info['stat'] = res['stat']
            return info
        return False

    def get_cid(self, aid):
        res = self.open_url(f"https://api.bilibili.com/x/player/pagelist?aid={aid}&jsonp=jsonp").json()
        if res['message'] == '0':
            cid = res["data"][0]["cid"]
            return cid
        return False

    def download_video(self, aid, cid, filename):
        res = self.open_url(f"https://api.bilibili.com/x/player/playurl?avid={aid}&cid={cid}&qn=64").json()
        url = res["data"]["durl"][0]["url"]
        print(f"准备下载{filename}...")
        f = open(filename, "ab")
        print("开始下载...")
        video = self.open_url(url)
        f.write(video.content)
        print("下载已完成!")

    def main(self):
        bv = input("请输入视频BV或AV号:")
        aid = self.BV_to_AV(bv)
        cid = self.get_cid(aid)
        if not cid:
            print("您输入的BV或AV号有误!")
            return False
        info = self.get_video_info(aid, cid)
        self.download_video(aid, cid, info['title'] + ".flv")
        return True

DBV = Download_Bilibili_Video()
if __name__ == "__main__":
    DBV.main()
复制成功


小甲鱼完结版 Python 教程:

最新版 Python 教程【连载中】:

小姐姐解读版:

网页链接​微软官方三部曲: