Python:哔哩哔哩B站视频下载,我终于对小破站下手了

前言

众所周知,B站的视频是以Blob的方式分断传输视频的,网上也有很多使用拼接视频来达到下载的目的的,但是这样的效率很低,这篇文章提供了三种其它的思路去下载小破站的视频。

开发环境

python 3.7.3

一、模拟手机

谷歌浏览器有模拟手机的功能,直接切到手机模式去打开视频播放页,就能拿到视频的源URL。
手机直接获取URL
OK,这里就有源地址了,说明我们就拿的到,看看它响应给我们的内容有什么:

var options = {
            aid: 929284665,
            bvid: 'BV1RK4y1Q76M',
            cid: 300249317,
            readyPoster: '//i1.hdslb.com/bfs/archive/e3653786d363a4e37dc01f5c8f1dd88791250472.jpg@480w_270h_1c',
            readyVideoUrl: 'https://cn-zjhz-cmcc-v-01.bilivideo.com/upgcxcode/17/93/300249317/300249317-1-16.mp4?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfq9rVEuxTEnE8L5F6VnEsSTx0vkX8fqJeYTj_lta53NCM=&uipk=5&nbs=1&deadline=1613912417&gen=playurl&os=vcache&oi=3083915405&trid=51606b49936a4e51a082be26ad4c9d00h&platform=html5&upsig=4c15f223ebed1d8cd7d4ca88ae18fb96&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,platform&cdnid=4059&mid=56446197&logo=80000000',
            readyDuration: 211,
            noRecommend: gqs('from') == 'game'
          }

一眼就看到视频源地址了,代码实现获取源地址。

# 获取视频url
def get_video_url(url, headers):
	# GET方式请求网站
    req = request.Request(url, headers=headers, method="GET")
    try:
    	#获取到HTMl
        response = request.urlopen(req).read().decode('utf-8')
    except error.HTTPError as e:
        print(e)
        print('\r\n' + url + 'download failed' + '\r\n')
    # 正则表达式提取视频URL
    video_url = re.search(r"readyVideoUrl: '(.*)?'", response)[0][16: -1]
    return video_url

拿到视频源地址,想干嘛就能干嘛了。但是这样的方法有个大缺点,就是视频的清晰度是360P的,属实有点低。

二、浏览器的方法

尝试干掉浏览器中video标签的src内容,如下图,再次刷新页面。

<video preload="auto" src="blob:https://www.bilibili.com/f6604c86-c729-4811-b643-8f03117524c8"></video>

video标签里的内容又重新加载出来了,并且Network里出现了一条不太眼熟的请求。

https://api.bilibili.com/x/player/playurl?cid=300249317&bvid=BV1RK4y1Q76M&qn=80&type=&otype=json&fourk=1&fnver=0&fnval=80

看响应内容:

"video": [
        {
          "id": 80,
          "baseUrl": "https://xy183x211x222x233xy.mcdn.bilivideo.cn:4483/upgcxcode/17/93/300249317/300249317-1-30080.m4s?expires=1613913782&platform=pc&ssig=FIiyAdg2RQ1B2vConj9UCw&oi=3083915405&trid=746221becc7249988cb157cc2f284567u&nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&mcdnid=1001366&mid=56446197&orderid=0,3&agrr=0&logo=A0000001",
          "base_url": "https://xy183x211x222x233xy.mcdn.bilivideo.cn:4483/upgcxcode/17/93/300249317/300249317-1-30080.m4s?expires=1613913782&platform=pc&ssig=FIiyAdg2RQ1B2vConj9UCw&oi=3083915405&trid=746221becc7249988cb157cc2f284567u&nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&mcdnid=1001366&mid=56446197&orderid=0,3&agrr=0&logo=A0000001",
          "backupUrl": [
            "https://xy183x211x222x212xy.mcdn.bilivideo.cn:4483/upgcxcode/17/93/300249317/300249317-1-30080.m4s?expires=1613913782&platform=pc&ssig=FIiyAdg2RQ1B2vConj9UCw&oi=3083915405&trid=746221becc7249988cb157cc2f284567u&nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&mcdnid=1001380&mid=56446197&orderid=1,3&agrr=0&logo=60000001",
            "https://cn-jssz-cmcc-v-06.bilivideo.com/upgcxcode/17/93/300249317/300249317-1-30080.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1613913782&gen=playurl&os=vcache&oi=3083915405&trid=746221becc7249988cb157cc2f284567u&platform=pc&upsig=27e3b8e1d5c6ce95884b710c549cafcc&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,platform&cdnid=5204&mid=56446197&orderid=2,3&agrr=0&logo=40000000"
          ],
          "backup_url": [
            "https://xy183x211x222x212xy.mcdn.bilivideo.cn:4483/upgcxcode/17/93/300249317/300249317-1-30080.m4s?expires=1613913782&platform=pc&ssig=FIiyAdg2RQ1B2vConj9UCw&oi=3083915405&trid=746221becc7249988cb157cc2f284567u&nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&mcdnid=1001380&mid=56446197&orderid=1,3&agrr=0&logo=60000001",
            "https://cn-jssz-cmcc-v-06.bilivideo.com/upgcxcode/17/93/300249317/300249317-1-30080.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1613913782&gen=playurl&os=vcache&oi=3083915405&trid=746221becc7249988cb157cc2f284567u&platform=pc&upsig=27e3b8e1d5c6ce95884b710c549cafcc&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,platform&cdnid=5204&mid=56446197&orderid=2,3&agrr=0&logo=40000000"
          ],

出现视频的源地址了,剩下的就是花点儿时间琢磨一下这条url中的参数有什么作用就行了,所需要的参数必须有视频bvid和cid,qn是清晰度。bvid就是视频的BV号,直接获取就行,cid则需要继续找。接着看下面这条请求。

https://api.bilibili.com/x/player/pagelist?bvid=BV1RK4y1Q76M&jsonp=jsonp

这个请求响应内容包含了视频CID,小标题,分辨率等信息。

{
  "code": 0,
  "message": "0",
  "ttl": 1,
  "data": [
    {
      "cid": 300249317,
      "page": 1,
      "from": "vupload",
      "part": "横屏",
      "duration": 106,
      "vid": "",
      "weblink": "",
      "dimension": {
        "width": 3840,
        "height": 2160,
        "rotate": 0
      }
    },
    {
      "cid": 300249655,
      "page": 2,
      "from": "vupload",
      "part": "竖屏手机版",
      "duration": 105,
      "vid": "",
      "weblink": "",
      "dimension": {
        "width": 1080,
        "height": 1920,
        "rotate": 0
      }
    }
  ]
}

需要的东西够了,开始代码实现获取视频源地址。

class BiliBili:
    # 构造请求头
    __headers = {
        "User_Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36",
        "referer": "https://www.bilibili.com/",
    }

    def __init__(self, url):
        self.url = url

    # 获取BVID
    def __bvid(self):
        bvid = self.url.split('/')[len(self.url.split('/')) - 1]
        if '?' in bvid:
            bvid = bvid.split('?')[0]
        return bvid

    # 获取CID
    def __cid(self):
        url = f"https://api.bilibili.com/x/player/pagelist?bvid={self.__bvid()}&jsonp=jsonp"
        req = request.Request(url, headers=self.__headers, method="GET")
        reponse = request.urlopen(req).read().decode("utf-8")
        return json.loads(reponse)['data'][0]["cid"]

    # 设置cookie
    def set_cookie(self, cookie):
        self.__headers['cookie'] = cookie

    # 获取视频url
    def video_url(self):
        url = f"https://api.bilibili.com/x/player/playurl?avid=&cid={self.__cid()}&bvid={self.__bvid()}&qn=120&type=&otype=json"
        req = request.Request(url, headers=self.__headers, method="GET")
        response = request.urlopen(req).read().decode("utf-8")
        return json.loads(response)['data']['durl'][0]['url']

同样,获取到了视频的源地址,剩下的就个人发挥了。

三、哔哩哔哩APP

其实哔哩哔哩有桌面客户端的,只是用的人不多,也没见B站推广。如果仅仅是下载视频的需求的话,直接用客户端就可以,相当简单快捷。
哔哩哔哩客户端
直接在Windows电脑的微软商店去搜索“哔哩哔哩”,免费下载安装里面的“哔哩哔哩动画”,喜欢哪个视频直接动动发财的小手点一下下载按钮即可。

总结

以上就是B站视频的三种下载方式了,完整的代码我放在Github上,请移步:https://github.com/KingJeeWhy/bilibili。另外,谢谢各位看官点的赞了。最后,文章内容仅作为交流和学习,请不要用做不良用途,希望小破站能越来越好。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值