《python爬虫练习》之b站视频下载

前言

因为网页B站没有下载视频和缓存视频(手机App有缓存)的功能,所以如果是想下载教学视频我们就需要用到一些第三方工具,讲真的,这真的很不方便,希望阿b能够重视。我们看其他视频可能是一次过,但教学视频可是要重复复习的,没WiFi真的很费流量。

 

爬取任务:下载B站视频 (单个)

分析B站

进入B站 ,使用f12进入开发者模式进行分析(小试牛刀,这里随便选择比较短的小视频(BV1H54y1y7Uu) )

因为我们要爬的是视频文件,所以可以直接筛选媒体,看类型是mp4的文件即可  

 这里有很多MP4文件,我们可以将请求链接复制到新窗口中打开,看看是不是我们所要的文件

这里有几点需要注意:

1.B站视频是将视频和音频分开的,所以我们需要分两次下载视频和音频文件,然后再通过其他方法合并成一个视频文件。

2.我们筛选出来的视频文件很多个,而且小,实际下载是要下载所有的文件,再合并在一起(分流)

3.如果我们选择的是登录之后才可以看的分辨率(720p,1080p,1080p+),那么控制台里只有音频文件,没有视频文件,所以请选择480p或者360p

写代码

import requests
# 请求地址
videoUrl = "https://119-125-42-88.mcdn.bilivideo.cn:480/upgcxcode/05/39/236663905/236663905_nb2-1-30032.m4s?" \
           "expires=1601117585&" \
           "platform=pc&" \
           "ssig=MHr0k25ViKeP8eA1VXR3dA&oi=3072822301&" \
           "trid=a08bb44076764a62908958806a65830cu&" \
           "nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&" \
           "mcdnid=1000933&mid={你的mid}&" \
           "orderid=0,3&" \
           "agrr=1&logo=A0000001"
# 请求头,即需要传递的参数
headers={
    'Host': '119-125-42-88.mcdn.bilivideo.cn:480',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
    'Accept': '*/*',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate, br',
    'Range': 'bytes=153191-393637',
    'Origin': 'https://www.bilibili.com',
    'Connection': 'keep-alive'
}
#移除SSL认证
requests.packages.urllib3.disable_warnings()
res = requests.get(videoUrl,headers=headers,verify=False)
with open('测试视频.mp4','wb')as f:
    f.write(res.content)
    f.close()

执行以上代码,我们可以得到234kb的MP4格式的文件,但该文件无法打开  

无法打开的原因很简单,我们下载的视频文件并不完整的文件,我们所下的不过是整个视频数据里的一小片段。

我们去分析所有的视频文件会发现,每个文件请求数据中, 'Range': 的数值都会发生改变。

我们可以做一个简单的推理,如上“Range”的数据为bytes=153191-393637,我们知道byte是字节的意思,那么393637-153191=240446,通过换算就是我们下载的文件大小。

说明range决定我们下载的视频片段,知道这点后,我们要下载完整视频只需要下载0到视频大小即可。

当然,我们并不能一眼看出要下载的视频有多大,所以也可以直接选择不传该参数

import requests
# 请求地址
videoUrl = "https://119-125-42-88.mcdn.bilivideo.cn:480/upgcxcode/05/39/236663905/236663905_nb2-1-30032.m4s?" \
           "expires=1601117585&" \
           "platform=pc&" \
           "ssig=MHr0k25ViKeP8eA1VXR3dA&oi=3072822301&" \
           "trid=a08bb44076764a62908958806a65830cu&" \
           "nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&" \
           "mcdnid=1000933&mid={你的mid}&" \
           "orderid=0,3&" \
           "agrr=1&logo=A0000001"
# 请求头,即需要传递的参数 ,有些无关参数可以不传
headers={
    # 'Host': '119-125-42-88.mcdn.bilivideo.cn:480',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
    'Accept': '*/*',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate, br',
    # 'Range': 'bytes=153191-393637',
    # 'Origin': 'https://www.bilibili.com',
    'Connection': 'keep-alive'
}
#移除SSL认证
requests.packages.urllib3.disable_warnings()
res = requests.get(videoUrl,headers=headers,verify=False)
with open('测试视频.mp4','wb')as f:
    f.write(res.content)
    f.close()

执行结果: 

 很明显可以看出与之前下载的文件有什么不同,这个文件就是我们要下的视频文件(也可以打开验证)。

音频同理,稍微分析就会知道,只需修改请求地址url即可,然后下载的文件后缀名改为mp3即可。

爬取高清晰度视频

上面说到,如果我们选择高清晰度的视频,控制台是不会返回相应清晰度的视频文件,那么我们怎么爬取高清晰度的视频呢?

这里就需要我们去分析源代码,看是否包含相关地址

使用ctrl+f搜索含有“.m4s”的内容

经过分析,发现我们要的url保存在一个window._playinfo_的json字符串中,我们将该字符串转换为json格式可清晰明了的找到我们所要的数据

因为1080p+,也就是id为112的请求链接需要有会员的mid才能使用,所以这里只取id为64的url,也就是720p的视频(貌似也没有112的)  

然后替换掉我们先前的url即可

import requests
# 请求地址
# videoUrl = "https://119-125-42-88.mcdn.bilivideo.cn:480/upgcxcode/05/39/236663905/236663905_nb2-1-30032.m4s?" \
#            "expires=1601117585&" \
#            "platform=pc&" \
#            "ssig=MHr0k25ViKeP8eA1VXR3dA&oi=3072822301&" \
#            "trid=a08bb44076764a62908958806a65830cu&" \
#            "nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&" \
#            "mcdnid=1000933&mid={你的mid}&" \
#            "orderid=0,3&" \
#            "agrr=1&logo=A0000001"
videoUrl720p="http://116-5-161-217.mcdn.bilivideo.cn:480/upgcxcode/05/39/236663905/236663905_nb2-1-30064.m4s?" \
             "expires=1601119065&platform=pc&" \
             "ssig=GlOx5XzLgi0oVtIyGf2q5w&" \
             "oi=3072822301&trid=2aaa4c3962514b1aba5d2e74b4408dcbu&" \
             "nfc=1&nfb=maPYqpoel5MI3qOUX6YpRA==&mcdnid=1001021&" \
             "mid={你的mid}&orderid=0,3&" \
             "agrr=1&logo=A0000001"
# 请求头,即需要传递的参数
headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
    'Accept': '*/*',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding': 'gzip, deflate, br',
    'Connection': 'keep-alive'
}

#移除SSL认证
requests.packages.urllib3.disable_warnings()
res = requests.get(videoUrl720p,headers=headers,verify=False)
with open('测试视频720.mp4','wb')as f:
    f.write(res.content)
    f.close()

 

 这里音频不受视频清晰度影响,所以随便下载一个音频,然后与想要的视频文件合成即可

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值