1. 程式人生 > 實用技巧 >Python爬蟲進階之爬取某視訊並下載,沒有廣告的視訊看起來不爽嗎?

Python爬蟲進階之爬取某視訊並下載,沒有廣告的視訊看起來不爽嗎?

本文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯絡我們以作處理

本文章來著騰訊雲 作者:python學習教程

意外的挖掘到了一個資源網站(你懂得),但是網速慢廣告多下載不了種種原因讓我突然萌生了爬蟲的想法。

下面說說流程:

一、網站分析

首先進入網站,F12檢查,本來以為這種低端網站很好爬取,是我太低估了web主。可以看到我重新整理網頁之後,出現了很多js檔案,並且響應獲取的程式碼與原始碼不一樣,這就不難猜到這個網站是動態載入頁面。

目前我知道的動態網頁爬取的方法只有這兩種:

1、從網頁響應中找到JS指令碼返回的JSON資料;

2、使用Selenium對網頁進行模擬訪問。

二、寫程式碼

匯入相關模組

import requestsfrom datetime import datetimeimport re#import jsonimport timeimport os #視訊分類和視訊列表URL的前一段url = "http://xxxxxxx/api/?d=pc&c=video&"#m3u8檔案和ts檔案的URL前一段m3u8_url ='https://xxxxxxxxxxxxx/videos/cherry-prod/2020/03/01/2dda82de-5b31-11ea-b5ae-1c1b0da2bc3f/hls/480/'#構造請求頭資訊header = {"user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2"}#建立空列表存放視訊資訊vediomassag=''#返回當前時間戳TimeStamp = int(datetime.timestamp(datetime.now()))

2.定義函式,獲取網站首頁分類列表資訊
#自定義函式獲取分類def get_vediocategory(url, TimeStamp):cgURL = url + "m=categories&timestamp=" + str(TimeStamp) + '&'response = requests.get(cgURL, headers=header)category = response.text# strrr='"%s"'%category# return strrrreturn category

3.定義函式,通過上一個函式返回的分類資訊,根據分類對應的id,輸入id並傳輸到當前URL中以便獲取分類下的視訊列表資訊
#獲取分類後的視訊列表def get_vedioList(url, TimeStamp, tagID):listURL = url + "m=lists&timestamp=" + str(TimeStamp) + '&' + "page=1&tag_id=" + str(tagID) + "&sort_type=&is_vip=0"response = requests.get(listURL, headers=header)vedioLists = response.textreturn vedioLists

4.在視訊列表資訊中獲取視訊對應的id,獲取單個視訊詳細資訊的URL
#獲取單個視訊的詳細資訊def get_vediomassages(url, TimeStamp, vedioID):videoURL = url + "m=detail&timestamp=" + str(TimeStamp) + '&' + "&id=" + str(vedioID)response = requests.get(videoURL, headers=header)vediomassag = response.textreturn vediomassag

5.在視訊詳細資訊中找到m3u8檔案的下載地址,並將檔案儲存到建立的檔案中
#將下載的m3u8檔案放進建立的ts列表檔案中def get_m3u8List(m3u8_url,vediomassag):lasturl = r'"m3u8_720_url":"(.*?)","download_url'last_url =re.findall(lasturl,vediomassag)lastURL=m3u8_url+str(last_url)response = requests.get(lastURL, headers=header)tsList = response.textcur_path='E:\\files' #在指定路徑建立資料夾try:if not os.path.isdir(cur_path): #確認資料夾是否存在os.makedirs(cur_path) #不存在則新建except:print("資料夾存在")filename=cur_path+'\\t2.txt' #在資料夾中存放txt檔案f = open(filename,'a', encoding="utf-8")f.write(tsList)f.closeprint('建立%s檔案成功'%(filename))return filename

6.將m3u8檔案中的ts單個提取出來放進列表中。
# 提取ts列表檔案的內容,逐個拼接ts的url,形成listdef get_tsList(filename):ls = []with open(filename, "r") as file:line = f.readlines()for line in lines:if line.endswith(".ts\n"):ls.append(line[:-1])return ls

7.遍歷列表獲取單個ts地址,請求下載ts檔案放進建立的資料夾中
# 批量下載ts檔案def DownloadTs(ls):length = len(ls)root='E:\\mp4'try:if not os.path.exists(root):os.mkdir(root)except:print("資料夾建立失敗")try:for i in range(length):tsname = ls[i][:-3]ts_URL=url+ls[i]print(ts_URL)r = requests.get(ts_URL)with open(root, 'a') as f:f.write(r.content)f.close()print('\r' + tsname + " -->OK ({}/{}){:.2f}%".format(i, length, i * 100 / length), end='')print("下載完畢")except:print("下載失敗")

程式碼整合
import requestsfrom datetime import datetimeimport re#import jsonimport timeimport os  url = "http://xxxxxxxx/api/?d=pc&c=video&"m3u8_url ='https://xxxxxxxxxxxxxxx/videos/cherry-prod/2020/03/01/2dda82de-5b31-11ea-b5ae-1c1b0da2bc3f/hls/480/'header = {"user-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2"}vediomassag=''TimeStamp = int(datetime.timestamp(datetime.now()))   #自定義函式獲取分類def get_vediocategory(url, TimeStamp):cgURL = url + "m=categories&timestamp=" + str(TimeStamp) + '&'response = requests.get(cgURL, headers=header)category = response.text# strrr='"%s"'%category# return strrrreturn category #獲取分類後的視訊列表def get_vedioList(url, TimeStamp, tagID):listURL = url + "m=lists&timestamp=" + str(TimeStamp) + '&' + "page=1&tag_id=" + str(tagID) + "&sort_type=&is_vip=0"response = requests.get(listURL, headers=header)vedioLists = response.textreturn vedioLists #獲取單個視訊的詳細資訊def get_vediomassages(url, TimeStamp, vedioID):videoURL = url + "m=detail&timestamp=" + str(TimeStamp) + '&' + "&id=" + str(vedioID)response = requests.get(videoURL, headers=header)vediomassag = response.textreturn vediomassag #將下載的m3u8檔案放進建立的ts列表檔案中def get_m3u8List(m3u8_url,vediomassag):lasturl = r'"m3u8_720_url":"(.*?)","download_url'last_url =re.findall(lasturl,vediomassag)lastURL=m3u8_url+str(last_url)response = requests.get(lastURL, headers=header)tsList = response.textcur_path='E:\\files' #在指定路徑建立資料夾try:if not os.path.isdir(cur_path): #確認資料夾是否存在os.makedirs(cur_path) #不存在則新建except:print("資料夾存在")filename=cur_path+'\\t2.txt' #在資料夾中存放txt檔案f = open(filename,'a', encoding="utf-8")f.write(tsList)f.closeprint('建立%s檔案成功'%(filename))return filename # 提取ts列表檔案的內容,逐個拼接ts的url,形成listdef get_tsList(filename):ls = []with open(filename, "r") as file:line = f.readlines()for line in lines:if line.endswith(".ts\n"):ls.append(line[:-1])return ls  # 批量下載ts檔案def DownloadTs(ls):length = len(ls)root='E:\\mp4'try:if not os.path.exists(root):os.mkdir(root)except:print("資料夾建立失敗")try:for i in range(length):tsname = ls[i][:-3]ts_URL=url+ls[i]print(ts_URL)r = requests.get(ts_URL)with open(root, 'a') as f:f.write(r.content)f.close()print('\r' + tsname + " -->OK ({}/{}){:.2f}%".format(i, length, i * 100 / length), end='')print("下載完畢")except:print("下載失敗")  '''# 整合所有ts檔案,儲存為mp4格式(此處函式複製而來未做實驗,本人直接在根目錄命令列輸入copy/b*.ts 檔名.mp4,意思是將所有ts檔案合併轉換成自己命名的MP4格式檔案。)def MergeMp4():print("開始合併")path = "E://mp4//"outdir = "output"os.chdir(root)if not os.path.exists(outdir):os.mkdir(outdir)os.system("copy /b *.ts new.mp4")os.system("move new.mp4 {}".format(outdir))print("結束合併")'''if __name__ == '__main__':# 將獲取的分類資訊解碼顯示出來# print(json.loads(get_vediocategory(url, TimeStamp)))print(get_vediocategory(url, TimeStamp))tagID = input("請輸入分類對應的id")print(get_vedioList(url, TimeStamp, tagID))vedioID = input("請輸入視訊對應的id")get_vediomassages(url, TimeStamp, vedioID)get_m3u8List(m3u8_url,vediomassag)get_tsList(filename)DownloadTs(ls)# MergeMp4()

此時正在下載