1. 程式人生 > >某站視訊python抓取: m3u8轉mp4

某站視訊python抓取: m3u8轉mp4

之前利用python簡單爬蟲抓過一些圖片,最近想到了抓取視訊。由於很多地方視訊不提供下載。所以覺得有必要學習一下,以備不時之需。備註:這裡僅記錄碰到的網站視訊例項,不保證適用所有情況。

基本概念與思路
目標問題是,在某視訊網站下載喜歡的視訊檔案並儲存為MP4格式。這裡涉及到幾種檔案格式。一般網路視訊都採用的流協議,具體內容非專業領域不是很瞭解,不深入討論。在我想抓取的視訊站中,發現原視訊資料分割為很多個TS流,每個TS流的地址記錄在m3u8檔案列表中,如圖所示:
M3U8

所以解決問題的思路邊是:第一步,抓取目標視訊的m3u8的地址URL;第二步,提取提取TS流;最後,合併流成MP4格式。 在搜素相關解決辦法時,發現可以利用FFMPEG可以直接實現m3u8 轉MP4。流程圖如下:

Created with Raphaël 2.1.2開始獲取m3u8 url獲取ts流合成mp4結束

程式碼實現:

import re
import uuid
import subprocess
import requests

QUALITY = 'ld' # video quality maybe 'ld' 'sd' or  'hd'
def get_video_ids_from_url(url):

     html = requests.get(url, headers=HEADERS).text
     video_ids = re.findall(r'data-lens-id="(\d+)"'
, html) #print(video_ids) if video_ids: return set([int(video_id) for video_id in video_ids]) return [] def yield_video_m3u8_url_from_video_ids(video_ids): for video_id in video_ids: api_video_url = 'https://lens.zhihu.com/api/videos/{}'.format(int(video_id)) # 下載的是知乎視訊
#print(api_video_url) r = requests.get(api_video_url, headers=HEADERS) playlist = r.json()['playlist'] print(playlist) m3u8_url = playlist[QUALITY]['play_url'] yield m3u8_url def download(url): video_ids = get_video_ids_from_url(url) m3u8_list = list(yield_video_m3u8_url_from_video_ids(video_ids)) filename = '{}.mp4'.format(uuid.uuid4()) path = "" for idx, m3u8_url in enumerate(m3u8_list): # here \" and \" is important! cmd_str = 'ffmpeg -i \"' + m3u8_url + '\" ' + '-acodec copy -vcodec copy -absf aac_adtstoasc ' + path + filename.format(str(idx)) print(cmd_str) subprocess.call(cmd_str,shell=True ) if __name__ == '__main__': # 貼上你需要下載的 回答或者文章的連結 url = 'your video page url' download(url)

上面程式碼自動搜素m3u8檔案連結,如果不是批處理,可手動查詢地址然後進行後續轉碼。在方法windows 與linux 均有效。