爬取嗶哩嗶哩小視頻
前言:想必大家都對小視頻感興趣吧,今天的爬蟲的內容爲將嗶哩嗶哩中的視頻下載到本地,今天爬取的網站爲
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標籤就可以下載御宅文化中其它類型的視頻
結語:今天的內容到這裏就結束了,如果大家覺得文章還不錯或者代碼還可以怎麼改進的話,可以在下方留言告訴我,我都會汲取大家的意見並和大家一起學習成長。