很多时候我们去之前的文件里找寻自己喜欢的视频,发现已经被下架了,这说明收藏并不能保证下一次的观看和使用,还是保存下载更靠谱一些。那么有没有什么爬虫方法可以把我们之前收藏里的视频全部爬取下来呢?考虑到大家平时收藏的视频数量也不少,如果是单个视频的爬取速度未免过慢,今天小编就教大家用多线程快速获取视频的方法吧。
先看请求的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=ℴ=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,自己解析太麻烦了)。
下载完成后:
我们之所以选择多线程也是因为下载是多个进程同时进程的,在效率方面优于我们以往传统的逐个下载。以后有类似大批量的下载需求,大家也可以使用多线程的爬取方法。
神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试