日常跳转:
很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!??¤
QQ群:623406465
导入与简介
转载请标明作者和原文链接!!!
CSDN个人主页: 高智商白痴
原文地址: https://blog.csdn.net/qq_44700693/article/details/108828909
规则更新日期: 2020-9-27
说起B站,肯定人人都知道吧,B站的反扒机制并不是太严格,所以今天我准备给大家说说我能想到的几种方式,目前大概想到了三种方式:
- 1、模拟手机端请求,视频链接就添加在源码中。(最简单、但清晰度不好)
- 2、通过调用别人的接口来下载视频。(根据接口的破解难度而定,可选择清晰度,不过最高的清晰度仅为未登录时能观看的最大清晰度)
- 3、直接通过B站的网页版来抓取。(难度稍大,不过清晰度很好,有大会员的话,能下载4K视频)
那么接下来我就来依次给大家介绍介绍我的方法!
方法一
为了方便分析,先拿一个链接作为测试:
https://www.bilibili.com/video/BV1R54y1e7J3?spm_id_from=333.5.b_646f7567615f6d6164.4
既然方法一已经确定是模拟手机端的方式去请求,那么我们就直接开始分析:
对该链接进行抓包,找了半天,并没有找到什么有用的信息,所以我就直接去查看网页源码:
- video_url = re.findall(’,“url”:"(.*?)",“backup_url”’, r.text)[0] .encode(‘utf-8’).decode(‘unicode_escape’)
标黄字体之前的代码为正则表达式的基本操作,而标黄的字体的原因是:
从源码中提取的到的链接为:
http:\u002F\u002Fupos-sz-mirrorkodo.bilivideo.com \u002F upgcxcode \u002F 10 \u002F 14 \u002F 230501410 \u002F 230501410-1-16.mp4?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfq9rVEuxTEnE8L5F6VnEsSTx0vkX8fqJeYTj_lta53NCM=&uipk=5&nbs=1&deadline=1601216024&gen=playurl&os=kodobv&oi=1971851232&trid=fcde238782674b78bf4425427c2a9ea3h&platform=html5&upsig=b98cc40700e7f05e614acf0acbd9b671&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,platform&mid=262968904&logo=80000000
链接中包含了大量的 \u002F 字段,这是因为源码中加载的是转换为 Unicode 编码后的链接,所以要进行编码转化。
方法二
为了方便分析,我还是拿之前的链接来作为测试:
https://www.bilibili.com/video/BV1R54y1e7J3?spm_id_from=333.5.b_646f7567615f6d6164.4
对于方法二,我们首先需要找到一个第三方的网站来解析视频,然后将整个过程进行包装。
不同的网站有不同的解析方式,我这里只写出我随便选择的一个网站,清晰度就还行吧。
介于这个网站的特殊性:当输入链接为:
https://www.bilibili.com/video/BV1R54y1e7J3?spm_id_from=333.5.b_646f7567615f6d6164.4 时会出现以下报错
将准备好的链接放到解析网站可以得到以下信息:
这是为了防止这个 B 站视频解析服务网站被滥用。在这里我对该解析网站进行了隐藏,想要使用这个解析服务的地址,可以私信我。
这种解析网站的一种特点就是,知道的人越多,它失效的也就越快。
希望这样,它可以尽量活得久一点点。
- 初始化中为什么含有两个请求头信息。
1、header1 的请求头信息为解析网站时所需要的一些信息。
2、header2 的请求头信息为下载视频时所需要的一些信息。
请求头为什么要分开写成两个:
第一个请求头所需的信息就不用多说,都是常规操作。第二个请求头所需是信息时因为该网站所解析出的视频链接为B站中的原链接,所以要带上关于B站信息的请求头来进行下载,否则服务器将会 拒绝 我们访问。
- data数据是什么:
在上述解析网站的操作过程中我们还记得,在请求完解析链接后,仍然需要选择视频文件的格式,我们才能得到视频的链接,而当我们选择完格式以后,会再次对原链接进行请求,并且会携带上固定格式的data数据。
- quote(‘http://www.****.com/video?url={}&page=video&submit=视频下载’.format(self.url))
为什么要进行编码转换:
网站就是这样,不更换编码,它要报错,嘿嘿嘿。
- video_url = re.findall(‘href="(.*?)"’, r.json()[‘msg’])[0] .replace(‘amp;’, ‘’)
同之前所说的,未标黄的部分也还是基本操作,就是利用正则表达式来提取信息,而对于所标黄的部分,这是因为所解析到的链接中含有 HTML的转移字符:
http://cn-cq-gd-bcache-15.bilivideo.com/upgcxcode/10/14/230501410/230501410-1-80.flv?e=ig8euxZM2rNcNbu1hbUVhoMahWNBhwdEto8g5X10ugNcXBlqNxHxNEVE5XREto8KqJZHUa6m5J0SqE85tZvEuENvNC8xNEVE9EKE9IMvXBvE2ENvNCImNEVEK9GVqJIwqa80WXIekXRE9IMvXBvEuENvNCImNEVEua6m2jIxux0CkF6s2JZv5x0DQJZY2F8SkXKE9IB5QK &deadline=1601220310 & gen=playurl & nbs=1 & oi=1696943910 & os=bcache & platform=pc &trid=380e02a6015c4f6c89df5944e35a87a8 & uipk=5 & upsig=062c2af07c4454f8641dc7552b1c1f3e &uparams=e,deadline,gen,nbs,oi,os,platform,trid,uipk & mid=0
方法三
对于方法三,既然选择直接去官网直接爬取,就需要分析网站的请求信息:
我们依然拿之前的链接来做测试:
https://www.bilibili.com/video/BV1R54y1e7J3?spm_id_from=333.5.b_646f7567615f6d6164.4
打开网页进行抓包可以看到,对于视频播放时的数据请求为两种形式:
- 1、…230501410-1-30080.m4s?..
- 2、…230501410-1-30280.m4s?..
这种情况也很常见,网站将音频和视频分隔开,分别进行请求得到我们所看到的视频。
但是!要怎么分辨谁是谁呢?
我们都知道视频所占字节比音频多,所以答案就是谁大谁就是视频的请求链接。我们对两个链接线进行尝试性的请求:
经过反复的尝试我发现请求头中的 range 参数是必不可少的,当前请求的 range 的范围为998814-1198620,但是因为只下载中间的片段,播放器不能识别出编码格式并解码,所以我将首位置修改成了 0。
实验证明我们的确能够得出这两个请求链接一个为音频一个为视频,并且链接具有时效性。
至于音频和视频的系啊在格式都设为 flv ,当该链接为音频时播放是没有画面的。
而如果想要下载整个视频或整个音频, range 的右值怎么设置呢?
方法有多种,我再这里把我能够想到的写出来:
- 1、先用一个小范围的 range 来请求链接,可以从返回的信息中的 Content-Length 字段得到下一次的请求范围。然后一直发送不同大小的请求,直到请求完成。
- 2、直接将 range 的范围定为 0-一个足够大的数,怎样才算足够大呢?只要大小大于或等于视频或音频的字节数就好。
- 3、这第三种就是我要使用的一种,因为它特别简单:直接将 range 的范围定为 0-(注意是数字 0 和一个 - ),则链接就会返回从0开始到结束时的数据。
如果还有什么新的方法,欢迎留言分享!
但是!就算知道了谁是谁,怎么请求,请求的链接又从哪里来呢?
我翻遍了请求链接都没有找到有用的信息,直到我查看到网页的源码:
如果你有B站大会员的话,可以填写自己的 cookie ,支持下载 4K 视频。亲测有效!!!