您的位置:首页 > 编程语言 > Python开发

Python网络爬虫实战(五)批量下载B站收藏夹视频

2019-09-28 10:38 2386 查看

我们除了爬取文本信息,有的时候还需要爬媒体信息,比如视频图片音乐等。就拿B站来说,我的收藏夹内的视频可能随时会失效,所以把它们下载到本地是非常保险的一件事。

对于这种大量列表型的数据,可以猜测B站收藏夹的请求中,详细的收藏详细可能会是异步加载的,因为这部分数据可能比较庞大。

我们来分析一下网络请求。

可以看到对收藏夹的请求是指定URL加收藏夹的id号,我们爬取的前提是这个收藏夹是公共收藏夹,不然是无法访问的。

再来看他的返回,明显没有收藏视频的信息,所以可以判断收藏视频的信息是通过api接口异步加载的。

详细查看一下其他的请求,你会发现这样一条。

可以看到这里返回了json数据,内容就是我们收藏夹中的视频,但是这里这有20个,再来看请求的URL。

https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id=88854277&pn=1&ps=20&keyword=&order=mtime&type=0&tid=0&jsonp=jsonp

media_id是收藏夹的id号,pn是代表哪一分页,ps是当前分页中视频数量。

那么我们就可以调用这个api来拿到所有收藏的视频了。

我们的视频分页当然不可能只有一页,所以我们可以遍历pn递增。

i = 1
while 1 :
url = 'https://api.bilibili.com/medialist/gateway/base/spaceDetail?media_id=88854277&pn='+ str(i) +'&ps=20&keyword=&order=mtime&type=0&tid=0&jsonp=jsonp'
html = requests.get(url)
i = i + 1
print(html.text)

这样就能拿到一个收藏夹下所有视频了,当i超过收藏夹页数时,直接异常退出即可。

接下来我们需要解析出每一个视频的id。

根据之前说的json解析,我们很容易就能用

res['data']['medias']

来获得所有的视频,然后再根据下标解析出每一个视频。

res = json.loads(html.text)
len_video = len(res['data']['medias'])
for id in range(0,len_video):
create_thread(res['data']['medias'][id])

这样我们就可以获取当前页视频数量,然后创建线程进行下载了,因为下载是一个非常占IO的事情,如果你单线程执行,下载一个视频再下载另一个,这样会很慢,我们可以给每一个视频创建一个线程来提高速度。

def create_thread(res):
thread = myThread(res['id'],res['title'],res['id'])
thread.start()

创建线程的线程号是视频的id号,线程名是视频名。

class myThread(threading.Thread):  # 继承父类threading.Thread
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
download_video(self.threadID)

线程类如上,里面有两个函数,__init__是默认的线程初始化函数,里面就是我们创建线程时传入的id和name。第二个函数是线程执行时的run方法,也就是我们定义线程的具体要做的事,里面只有一个download_video方法。

# 下载视频
def download_video(av_id):
os.system('you-get -o d:/vedio/ https://www.bilibili.com/video/av'+str(av_id))

在下载函数中,我们可以调用you-get来帮助我们解析下载视频(不要问为什么调you-get,自己解析太麻烦了)。

这样我们就完成了。

下载完成后:

源码地址: https://github.com/CasterWx/VideoDown

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: