概述:本文采用python语言和scrapy应用框架批量采集下载b站视频,过程采用了模拟登录、Ajax动态加载和ffmpeg音视频合成技术,可关注本人公众号【Python是我哥】下载源码,也可加入Q群(756788325)讨论学习。
B站的资源实在太好,从性感美女的短裙热舞到理工宅男的代码技术,干货满满,可以说是个人娱乐和学习的不二之选。好的东西总是想拥有,所以就萌发了采集b站视频的想法
项目需求∶
目标是做到固定采集自己账号关注人中的某分组的全部发布视频,这样如果我想要什么视频,只需要关注并采集即可。
成果展示∶
在讲采集程序之前,先展示下采集成果吧,免得大家没动力往下看。
过程分析∶
想采集自己账号关注的某分组up主,那肯定需要能先登录自己账号。通过cookie模拟登录不难,先在网页登录自己的账号,然后在网络响应中找个带有cookie的请求。
拷贝下来放到请求headers里面直接请求即可实现模拟登陆。
DEFAULT_REQUEST_HEADERS = {
'referer': 'https://www.bilibili.com/',
'cookie': "buvid3=DD5186C3-ABB7-4BA9-A4AD-XXF78717D02A185013infoc; CURRENT_FNVAL=4048; _uuid=ED5CFF9C-64610-D956-DDAA-8DEE7DFF10FBA34258infoc; buvid4=F999A38E-661F-FD06-EF76-4E7222F4DD1F35257-022062120-ytBxrF8FyJ3KwRM6RFOcTQ==; CURRENT_BLACKGAP=0; blackside_state=0; b_nut=100; rpdid=|(k|k)RuuYlJ0J'uY~|YYm)mY; i-wanna-go-back=-1; buvid_fp_plain=undefined; b_ut=5; CURRENT_QUALITY=80; DedeUserID=488791404; DedeUserID__ckMd5=919d0cf182290288; SESSDATA=cc5e1e92,1687403253,3bee5*c1; bili_jct=05c6a149f90e05534f27053f9b2ce17e; sid=7nugwcqr; fingerprint=0191d1b28e0adcbb4528afe124827b77; buvid_fp=0191d1b28e0dcabb4528afe124827b77; bp_video_offset_488791404=742835806880661500; is-2022-channel=1; PVID=1; b_lsid=25857F75_18553DF608F; bsource=search_baidu; innersign=1",
}
接下来,我先挑关注中的【dancer】分组的其中一个up主的其中一个视频,打开其播放页。

通过查看网络响应,倒序查看其响应时长,视频资源一般会排在前几名,因为整个网页应该视频资源最大,自然其响应时长也会偏长。
这里找到6个m4s后缀的文件,其中前三个的请求url相同,后三个的请求url也相同。写个脚本下载下来,保存为mp4格式。果然可以播放,而且发现b站的视频和音频是分开两个请求的。之所以各自有三个响应,看响应码为206就知道它是分段请求的了。脚本代码如下∶
# -*- coding: utf-8 -*-
# @Time : 2023-01-04 18:41:59
# @Author : 愤怒的it男
# @Accounts :Python是我哥
# @File : demo.py
import requests
video_url = "https://xy111x42x162x205xy.mcdn.bilivideo.cn:4483/upgcxcode/56/62/946956256/946956256-1-100026.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1672833674&gen=playurlv2&os=mcdn&oi=2028411739&trid=0000c1083ffa6b204725b8f731b947da1a91u&mid=488791404&platform=pc&upsig=96796a9556c2eeadd5673801f81e9463&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform&mcdnid=1002865&bvc=vod&nettype=0&orderid=0,3&buvid=&build=0&agrr=0&bw=147368&logo=A0000001"
audio_url = "https://xy111x42x162x205xy.mcdn.bilivideo.cn:4483/upgcxcode/56/62/946956256/946956256_nb3-1-30280.m4s?e=ig8euxZM2rNcNbdlhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1672833674&gen=playurlv2&os=mcdn&oi=2028411739&trid=0000c1083ffa6b204725b8f731b947da1a91u&mid=488791404&platform=pc&upsig=f28ca4c1a960c2991b8ecc76825d9547&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform&mcdnid=1002865&bvc=vod&nettype=0&orderid=0,3&buvid=&build=0&agrr=0&bw=22128&logo=A0000001"
headers_ = {
'Referer': 'https://www.bilibili.com/',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36',
}
video_response = requests.get(video_url, headers=headers_)
audio_response = requests.get(video_url, headers=headers_)
video_data = video_response.content
audio_data = audio_response.content
with open("video.mp4", "wb") as f:
f.write(video_data)
with open("audio.mp3", "wb") as f:
f.write(audio_data)
那视频请求和音频请求的url哪里来的呢?播放页所有响应中搜索下,发现视频播放页的HTML源码中有出现,大概在“window.playinfo”位置,可以用xpath选择器解析出来。
playinfo = response.xpath('//script[contains(text(),"window.__playinfo__")]/text()')[0].get()
那视频播放页的请求url又是怎么来的呢?我们发现该url后面有一串不知道是啥的字符串【BV1uv4y1B7DZ】
盲猜是啥参数,并且在视频列表页应该有提供。因此可以回到视频列表页的所有响应中搜索该字符串,果不其然……
还是个json数据,我喜欢……这个json数据不仅能获取bvid这个参数,还能获取title、author和description,那这个json数据的请求url又是哪里来的呢?
看图片,该请求url主要有mid、tid、pn、ps等数据。pn应该是页码,ps应该是一页数据数,通过循环语句设置这两个参数可以遍历up主的所有视频。tid是自己的账号tid,这个在登录后主页url可以看到,固定的。
因此,只需知道mid就能构成视频列表页的请求url了,那mid哪里获取呢?应该是up主列表页有提供,果断返回up主列表页,在所有响应中搜索该mid,出来了……更开心的是这也是个json数据。
分析到这里,基本就可以上手写代码实现了。
流程梳理:
这里限于篇幅,也不可能把所有代码张贴出来,可关注公众号【Python是我哥】下载源码。整个代码实现流程如下:
1、模拟登录
2、请求up主列表页的json数据,遍历拿到每位up主的mid,构造每位up主视频列表的请求url
3、请求视频列表页的json数据,遍历拿到每个视频的bvid,构造每个视频播放页的请求url
4、请求视频播放页,解析出m4s格式的视频和音频的请求url
5、下载视频和音频,使用ffmpeg合成
免责声明:
本公众号所有源码均为个人学习所编写,仅可用于计算机技术学习及研究等合法行为,禁止利用本公众号的源码从事任何违反本国(地区)法律法规的业务,如有发现存在违法违规行为我会举报到网监部门。
网友评论