前言:想必大家都对小视频感兴趣吧,今天的爬虫的内容为将哔哩哔哩中的视频下载到本地,今天爬取的网站为
URL : https://vc.bilibili.com/p/eden/all#/?tab=%E5%BE%A1%E5%AE%85%E6%96%87%E5%8C%96&tag=COSPLAY
1. 分析站点
a) 进入网站后,鼠标滚动往下滚动,很明显可以看到这个网站的数据是通过ajax技术动态加载来的,所以第一步做的就是鼠标右键检查,进入Network→XHR,然后刷新页面再次将鼠标往下滚动,会发现在XHR中加载了很多的数据包
b) 找到加载的数据包后第二步要做的就是对这些数据进行分析,找出视频的播放地址及视频的名字,从这些加载的数据中我们找到了视频的播放地址video_playurl和视频的名称description,而且每个请求中都包含30个视频的信息
c) 找到我们保存视频时需要的名称和视频后,下一步就要开始分析返回这些数据的请求url了,最简单的办法就是通过反复点击这两个请求,很容易就可以看到只有next_offset的值在变化。而且所对应的值是30倍数
d) 我们尝试将next_offset的值改为0然后去发送请求,看是不是就是页面最开始的前30个视频的数据,发现就是最开始页面加载的数据,这说明next_offset的初始值为0,所以当我们在代码中请求数据的时候也要从next_offset为0开始发送请求下载视频
2. 上代码
分析完网页是信息后,我们只需要在代码中更改请求的url中的next_offset的值就可以下载不同的视频了,先写好大概的思路,然后再去慢慢完善代码
a) 写好大概的思路
import requests
class DouyinSpider(object):
def __init__(self):
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'}
self.url = 'https://api.vc.bilibili.com/clip/v1/video/search?page_size=30&need_playurl=0&next_offset={}&has_more=1&order=&tag=COSPLAY&platform=pc'
def parse_json(self,json):
pass
def request_page(self):
count = int(input('请输入你想要爬取的页数,一页30个视频:'))
for i in range(0,count):
response = requests.get(self.url.format(i*30)).json()
self.parse_json(response)
def save_video(self,video_url,title):
pass
def main(self):
self.request_page()
if __name__ == '__main__':
spider = DouyinSpider()
spider.main()
b) 完整代码
import requests,re,os
class DouyinSpider(object):
def __init__(self):
self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.113 Safari/537.36'}
self.url = 'https://api.vc.bilibili.com/clip/v1/video/search?page_size=30&need_playurl=0&next_offset={}&has_more=1&order=&tag=COSPLAY&platform=pc'
# 解析获取的数据,并从中提取出视频的播放地址和视频的名称
def parse_json(self,json):
items = json['data']['items'] # 视频的数据都放在items中,所以要去遍历items
for item in items:
video_url = item['item']['video_playurl'] # 提取出数据中的播放地址和视频的名称
title = item['item']['description']
self.save_video(video_url,title) # 将视频地址和视频名称传给save_video方法
# 发送请求获取数据
def request_page(self):
count = int(input('请输入你想要爬取的页数,一页30个视频:'))
for i in range(0,count):
response = requests.get(self.url.format(i*30)).json() # 将返回的json数据转为python中的数据类型
self.parse_json(response) # 将返回的数据传给parse_json方法
# 保存视频到本地
def save_video(self,video_url,title):
res = requests.get(video_url,headers=self.headers).content # 对视频的播放地址发送请求获取数据,因为视频是二进制数据,所以还需要将返回的数据转为二进制数据然后再去保存,所以这里需要.content
title = re.sub(r'[\,, .。/#!!??@\n\s::————丶*ノヽ*´з]','',title) # 使用re模块中的sub方法将非法的字符转为空字符串,不然保存视频时出错
filename = 'F:/视频/'
if not os.path.exists(filename): # 使用os库中的path模块判断filename路径是否存在,不存在则创建
os.makedirs(filename) # 创建多级目录
with open(filename+'{}.mp4'.format(title),'wb')as f:
f.write(res)
print('已下载{}'.format(title))
def main(self):
self.request_page()
if __name__ == '__main__':
spider = DouyinSpider()
spider.main()
c) 我下载了两页的的视频,下载的结果正好是60个视频,所以验证了我们之前分析的结果没有错误
3. 小思考
你们有没有发现请求url中有一个tag标签,其实可以通过改变tag标签就可以下载御宅文化中其它类型的视频
结语:今天的内容到这里就结束了,如果大家觉得文章还不错或者代码还可以怎么改进的话,可以在下方留言告诉我,我都会汲取大家的意见并和大家一起学习成长。