b站视频下载接口分析

最近无聊分析了一下b站的视频流协议,简单分享下爬取的流程。

 

首先先要找到视频对应的aid和cid,aid就相当于av号,而av号对应网页下的每一个视频都有对应的cid,普通视频就是分p,番剧就是集数,aid和cid在网页的源代码里面都能找到,用正则匹配aid和cid这两个关键字就能匹配到,如下代码:

1 url = ''  #这里是需要下载的视频网址
2 html = requests.get(url,headers).text
3 aid = json.loads(re.findall(r'"aid":(\d+)',html)[0])  #这里是aid
4 pages = json.loads(re.findall(r'"pages":(\[.+?\])',html)[0])
5 cidlist = []  #这里是cid的列表
6 for i in pages:
7     cidlist.append(i['cid'])  

 

b站视频流地址api如下:

https://api.bilibili.com/pgc/player/web/playurl?fnval=80&cid={c}  (这是番剧的)
https://api.bilibili.com/x/player/playurl?fnval=80&avid={a}&cid={c}  (这是视频的)
 
如上api会返回json字符串,包含各种支持的编码和分辨率的视频流,番剧只需要cid就能访问所以可以不提取aid,有些番剧和分辨率可能得大会员或者港澳台才能使用,如有需要请修改请求的cookie和ip地址。
其中关于video的json字符串如下:

"video": [
{
                "start_with_sap": 1,
                "bandwidth": 4112579,
                "sar": "1:1",
                "backupUrl": [""],
                "codecs": "avc1.640028",
                "base_url": "",
                "backup_url": [""],
                "segment_base": {
                    "initialization": "0-990",
                    "index_range": "991-4490"
                },
                "mimeType": "video/mp4",
                "frame_rate": "16000/672",
                "SegmentBase": {
                    "Initialization": "0-990",
                    "indexRange": "991-4490"
                },
                "frameRate": "16000/672",
                "codecid": 7,
                "baseUrl": "",
                "size": 0,
                "mime_type": "video/mp4",
                "width": 1920,
                "startWithSAP": 1,
                "id": 112,
                "height": 1080,
                "md5": ""
}]

其中的base_url、id和codecs字段是我们需要的。不同的id对应不同的分辨率,codecs对应编码方式,base_url就是对应分辨率和编码方式下的视频流地址。

audio对应的json字符串和video类似,同样是base_url为音频流地址。

(注意其上的api都得在请求头加referer字段,否则无法访问)

 

视频流地址可以在请求头加range字段,用于分段下载或者部分下载,如不加则为下载所有,代码如下:

headers = {
    'user-agent':'',
    'referer':'',
    'range':'byte=0-9999' #此为range字段,代表下载整个视频从0到9999字节的数据
}

with open('demo_vedio.mp4','wb+') as file1, open('demo_audio.mp3','wb+') as file2:
file1.write(requests.get(vedio_url,headers=headers).content) #下载video
file2.write(requests.get(audio_url,headers=headers).content) #下载audio

接下来就是等资源下载完毕了,如有需要可以用格式工厂将音频视频合并成为一个完整的视频。

 

总结:b站还是很友好的,没有弄一些加密什么的来防爬,通过这次也大致了解了hash协议的原理,总体来说想下载b站视频并不难。

 

b站视频下载相关的源码网址:https://github.com/modifyGB/bili_video_download

posted @ 2021-01-03 18:07  Epitaph  阅读(2272)  评论(0编辑  收藏  举报