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

1

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

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

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

2

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

3

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

4

可以看到这里返回了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,自己解析太麻烦了)。

这样我们就完成了。

12

下载完成后:

21

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

版权声明:本文为LexMoon原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/LexMoon/p/pyspider05.html