1. 批量爬取B站小視頻
嗶哩嗶哩網站(英文名稱: bilibili),是年輕人的文化社區,被粉絲們親切的稱為B站。該網站中擁有動畫、番劇、國創、音樂、舞蹈、游戲、科技、生活、鬼畜、娛樂、時尚等多個內容分區。那么我們能不能爬取一些視頻以后離線觀看呢?答案是肯定的。本任務要求使用Python語言中的爬蟲技術,實現批量爬取B站小視頻的爬蟲程序。爬取后的效果下圖所示。
分析過程如下:
點擊上面的排行榜之后,按F12調出瀏覽器控制臺調試界面,點擊Network,第一次進入Network可能是空的,按F5或者點擊瀏覽器左上角刷新一下即可,最后如圖所示。
但是需要注意的是,不是所有的數據都是根據一個固定的url返回的,如圖所示。
接下來就可以去完成代碼了,注意,因為爬蟲需要使用第三方模塊requests,所以讀者需要使用如下命令進行安裝。
pip install --user -i http://pypi.douban.com/simple --trusted-host pypi.douban.com requests1
如圖所示:
示例代碼如下:
import requests # 網絡請求模塊import os # 系統模塊import time # 時間模塊import re # 正則模塊import random # 隨機模塊json_url = "https://api.vc.bilibili.com/board/v1/ranking/top?page_size=10&next_offset={}1&tag=%E4%BB%8A%E6%97%A5%E7%83%AD%E9%97%A8&platform=pc" # 嗶哩嗶哩小視頻json地址class MySpider(object): # 定義一個spider類 # 初始化 def __init__(self): # 構造請求頭 self.headers = { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit" "/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"} # 請求json數據 def get_json(self, url): response = requests.get(url, headers=self.headers) # 根據返回的狀態碼判斷是否請求成功 if response.status_code == 200: return response.json() # 返回json信息 else: print("獲取json信息的請求沒有成功~") # 下載視頻 def download_video(self, url, video_name): # 下載視頻的網絡請求 response = requests.get(url, headers=self.headers, stream=True) if not os.path.exists("video"): # 判斷本地是否存在video文件夾 不存在則創建 os.mkdir("video") # 根據返回的狀態碼判斷是否請求成功 if response.status_code == 200: with open("video/" + video_name + ".mp4", "wb") as file: # 非純文本都以字節的方式寫入 for data in response.iter_content(chunk_size=1024): # 循環寫入 file.write(data) # 寫入視頻文件 file.flush() # 刷新緩存 print("視頻下載完成~") else: print("視頻下載失敗~")if __name__ == '__main__': # 程序的入口 spider = MySpider() for i in range(10): # 100條數據 需要發送10次循環 所以需要循環10次 json = spider.get_json(json_url.format(i)) video_infos = json["data"]["items"] # 信息集 一個列表 # 遍歷 獲取每一個video的信息 for video_info in video_infos: # 視頻的名字只保留標題中英文、數字與漢字 便于寫入文件 title = video_info["item"]["description"] comp = re.compile("[^A-Z^a-z^0-9^一-龥]") title = comp.sub("", title) # 其他字符一律替換為空 video_url = video_info["item"]["video_playurl"] # 視頻地址 print(title, video_url) # 打印提取的視頻標題與視頻地址 spider.download_video(video_url, title) # 下載視頻 視頻標題作為視頻的名字 time.sleep(random.randint(3, 6)) # 避免頻繁發送請求 ip被封
2. 獲取動態請求的JSON數據
在上面的批量爬取B站小視頻任務中,我們已經通過發送動態請求的方式,獲取到視頻的標題與視頻地址。為了更好的掌握JSON數據的提取技術,此次任務要求獲取JSON中視頻發布時間、用戶名稱以及觀看人數并打印。在PyCharm控制臺輸出的結果如圖所示。
這個任務的話其實就是在之前代碼的基礎上修改了一小部分,如圖所示:
3. 隨機生成瀏覽器的頭部信息
有時在請求一個網頁內容時,如果頻繁地使用一個固定的瀏覽器頭部信息發送網絡請求時,可能會出現403錯誤。產生這種錯誤是由于該網頁為了防止惡意采集信息而使用了反爬蟲設置,從而拒絕了用戶的訪問。所以本任務要求實現每發送一個網絡請求,就更換一個瀏覽器的頭部信息,避免使用固定的瀏覽器頭部信息。在PyCharm控制臺輸出的結果如圖所示。
安裝fake_useragent模塊并初步了解其基本應用,使用pip命令安裝fake_useragent模塊的命令如下:
pip install --user -i http://pypi.douban.com/simple --trusted-host pypi.douban.com fake_useragent1
如圖所示:
在這次的任務中,還需要一個json格式的文件,下載地址為:
鏈接:https://pan.baidu.com/s/1IeW70k6pd1HMZqOQ0jw1FQ 密碼:t67s1
示例代碼如下:
import requests # 網絡請求模塊import os # 系統模塊import time # 時間模塊import re # 正則模塊import random # 隨機模塊from fake_useragent import UserAgent # 導入偽造頭部信息的模塊json_url = "https://api.vc.bilibili.com/board/v1/ranking/top?page_size=10&ne" "xt_offset={}1&tag=%E4%BB%8A%E6%97%A5%E7%83%AD%E9%97%A8&platform=pc" # 嗶哩嗶哩小視頻json地址class MySpider(object): # 定義一個spider類 def get_json(self, url): # 請求json數據 headers = {"User-Agent": UserAgent(path="fake_useragent.json").random} # 創建隨機生成的頭部信息 print(f"當前下載請求的瀏覽器頭部信息為: {headers}") response = requests.get(url, headers=headers) # 根據返回的狀態碼判斷是否請求成功 if response.status_code == 200: return response.json() # 返回json信息 else: print("獲取json信息的請求沒有成功~") # 下載視頻 def download_video(self, url, video_name): headers = {"User-Agent": UserAgent(path="fake_useragent.json").random} # 創建隨機生成的頭部信息 # 下載視頻的網絡請求 response = requests.get(url, headers, stream=True) if not os.path.exists("video"): # 判斷本地是否存在video文件夾 不存在則創建 os.mkdir("video") # 根據返回的狀態碼判斷是否請求成功 if response.status_code == 200: with open("video/" + video_name + ".mp4", "wb") as file: # 非純文本都以字節的方式寫入 for data in response.iter_content(chunk_size=1024): # 循環寫入 file.write(data) # 寫入視頻文件 file.flush() # 刷新緩存 print("視頻下載完成~") else: print("視頻下載失敗~")if __name__ == '__main__': # 程序的入口 spider = MySpider() for i in range(10): # 100條數據 需要發送10次循環 所以需要循環10次 json = spider.get_json(json_url.format(i)) video_infos = json["data"]["items"] # 信息集 一個列表 # 遍歷 獲取每一個video的信息 for video_info in video_infos: # 視頻的名字只保留標題中英文、數字與漢字 便于寫入文件 title = video_info["item"]["description"] comp = re.compile("[^A-Z^a-z^0-9^一-龥]") title = comp.sub("", title) # 其他字符一律替換為空 video_url = video_info["item"]["video_playurl"] # 視頻地址 upload_time = video_info["item"]["upload_time"] # 視頻發布日期 user_name = video_info["user"]["name"] # 用戶名字 watched_num = video_info["item"]["watched_num"] # 觀看人數 print(f"視頻標題為: {title}") print(f"發布時間為: {upload_time}") print(f"視頻地址為: {video_url}") print(f"觀看人數為: {watched_num}") # spider.download_video(video_url, title) # 下載視頻 視頻標題作為視頻的名字 time.sleep(random.randint(3, 6)) # 避免頻繁發送請求 ip被封
4. 獲取要下載視頻的大小
在多數網站中下載視頻、音樂以及文本文件時,都可以看見當前文件的大小,如下圖所示。
本任務要求通過requests模塊下載指定視頻內容時,獲取其視頻的文件大小。在PyCharm控制臺輸出的結果如下圖所示。
示例代碼如下:
import requests # 網絡請求模塊import os # 系統模塊import time # 時間模塊import re # 正則模塊import random # 隨機模塊from fake_useragent import UserAgent # 導入偽造頭部信息的模塊json_url = "https://api.vc.bilibili.com/board/v1/ranking/top?page_size=10&ne" "xt_offset={}1&tag=%E4%BB%8A%E6%97%A5%E7%83%AD%E9%97%A8&platform=pc" # 嗶哩嗶哩小視頻json地址class MySpider(object): # 定義一個spider類 def get_json(self, url): # 請求json數據 headers = {"User-Agent": UserAgent(path="fake_useragent.json").random} # 創建隨機生成的頭部信息 response = requests.get(url, headers=headers) # 根據返回的狀態碼判斷是否請求成功 if response.status_code == 200: return response.json() # 返回json信息 else: print("獲取json信息的請求沒有成功~") # 下載視頻 def download_video(self, url, video_name): headers = {"User-Agent": UserAgent(path="fake_useragent.json").random} # 創建隨機生成的頭部信息 # 下載視頻的網絡請求 response = requests.get(url, headers=headers, stream=True) content_size = int(response.headers["content-length"]) # 視頻內容的總大小 if not os.path.exists("video"): # 判斷本地是否存在video文件夾 不存在則創建 os.mkdir("video") # 根據返回的狀態碼判斷是否請求成功 if response.status_code == 200: # 1MB=1024KB 1KB=1024B 我們返回的是多少B 推出==>KB==>MB print("視頻文件大小: %0.2fMB" % (content_size / 1024 / 1024)) # 換算單位 with open("video/" + video_name + ".mp4", "wb") as file: # 非純文本都以字節的方式寫入 for data in response.iter_content(chunk_size=1024): # 循環寫入 file.write(data) # 寫入視頻文件 file.flush() # 刷新緩存 print("視頻下載完成~") else: print("視頻下載失敗~")if __name__ == '__main__': # 程序的入口 spider = MySpider() ranking = 0 # 排名 for i in range(10): # 100條數據 需要發送10次循環 所以需要循環10次 json = spider.get_json(json_url.format(i)) video_infos = json["data"]["items"] # 信息集 一個列表 # 遍歷 獲取每一個video的信息 for video_info in video_infos: ranking += 1 print(f"正在下載排名第 {ranking} 的視頻") # 視頻的名字只保留標題中英文、數字與漢字 便于寫入文件 title = video_info["item"]["description"] comp = re.compile("[^A-Z^a-z^0-9^一-龥]") title = comp.sub("", title) # 其他字符一律替換為空 video_url = video_info["item"]["video_playurl"] # 視頻地址 print(f"視頻標題為: {title}") print(f"視頻地址為: {video_url}") spider.download_video(video_url, title) # 下載視頻 視頻標題作為視頻的名字 time.sleep(random.randint(3, 6)) # 避免頻繁發送請求 ip被封
5. 實時打印文件下載進度
在多數網站中下載視頻、音樂以及文本文件時,都可以看見當前文件的大小以及已經下載的大小,如下圖所示。
整個項目的代碼獲取后臺私信小編01
在之前的任務中,我們已經實現了顯示當前文件的大小。本任務要求將下載文件的實時進度打印出來。在PyCharm控制臺輸出的結果如下圖所示。
示例代碼如下:
import requests # 網絡請求模塊import os # 系統模塊import time # 時間模塊import re # 正則模塊import random # 隨機模塊from fake_useragent import UserAgent # 導入偽造頭部信息的模塊json_url = "https://api.vc.bilibili.com/board/v1/ranking/top?page_size=10&ne" "xt_offset={}1&tag=%E4%BB%8A%E6%97%A5%E7%83%AD%E9%97%A8&platform=pc" # 嗶哩嗶哩小視頻json地址class MySpider(object): # 定義一個spider類 def get_json(self, url): # 請求json數據 headers = {"User-Agent": UserAgent(path="fake_useragent.json").random} # 創建隨機生成的頭部信息 response = requests.get(url, headers=headers) # 根據返回的狀態碼判斷是否請求成功 if response.status_code == 200: return response.json() # 返回json信息 else: print("獲取json信息的請求沒有成功~") # 下載視頻 def download_video(self, url, video_name): size = 0 # 記錄疊加每次寫入的大小 headers = {"User-Agent": UserAgent(path="fake_useragent.json").random} # 創建隨機生成的頭部信息 # 下載視頻的網絡請求 response = requests.get(url, headers=headers, stream=True) content_size = int(response.headers["content-length"]) # 視頻內容的總大小 if not os.path.exists("video"): # 判斷本地是否存在video文件夾 不存在則創建 os.mkdir("video") # 根據返回的狀態碼判斷是否請求成功 if response.status_code == 200: # 1MB=1024KB 1KB=1024B 我們返回的是多少B 推出==>KB==>MB print("視頻文件大小: %0.2fMB" % (content_size / 1024 / 1024)) # 換算單位 with open("video/" + video_name + ".mp4", "wb") as file: # 非純文本都以字節的方式寫入 for data in response.iter_content(chunk_size=1024): # 循環寫入 file.write(data) # 寫入視頻文件 file.flush() # 刷新緩存 size += len(data) # 疊加每次寫入的大小 # 打印下載進度 print(" 文件下載進度:%d%%(%0.2fMB/%0.2fMB)" % ( float(size / content_size * 100), (size / 1024 / 1024), (content_size / 1024 / 1024)), end=" ") else: print("視頻下載失敗~")if __name__ == '__main__': # 程序的入口 spider = MySpider() ranking = 0 # 排名 for i in range(10): # 100條數據 需要發送10次循環 所以需要循環10次 json = spider.get_json(json_url.format(i)) video_infos = json["data"]["items"] # 信息集 一個列表 # 遍歷 獲取每一個video的信息 for video_info in video_infos: ranking += 1 print(f"正在下載排名第 {ranking} 的視頻") # 視頻的名字只保留標題中英文、數字與漢字 便于寫入文件 title = video_info["item"]["description"] comp = re.compile("[^A-Z^a-z^0-9^一-龥]") title = comp.sub("", title) # 其他字符一律替換為空 video_url = video_info["item"]["video_playurl"] # 視頻地址 print(f"視頻標題為: {title}") print(f"視頻地址為: {video_url}") spider.download_video(video_url, title) # 下載視頻 視頻標題作為視頻的名字 time.sleep(random.randint(3, 6)) # 避免頻繁發送請求 ip被封
到此就結束了這次的小案例了!
著作權歸作者所有,如有侵權聯系小編刪除!謝謝!
原文:https://blog.csdn.net/xw1680/article/details/105398418
總結
以上是生活随笔為你收集整理的json spr路驾驶技术视频api_每天弄个小爬取之Python爬取批量爬取B站小视频的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。