Closed TzuHanLiang closed 4 months ago
用於說明如何使用 Python 和 Selenium 從一個具有反爬蟲機制的網站上下載視頻。這個教程將透過幾個步驟引導操作者完成從獲取視頻源地址到使用 ffmpeg
下載視頻的整個過程。
通常情況下,可以使用 Python 的 requests
庫直接從網頁上的 <video>
標籤中獲得視頻源地址並下載視頻。然而,如果遇到具有動態加載技術或反爬蟲機制的網站,這種方法可能不適用。我們這裡要下載的立法院會議相關資訊的網站就有反爬蟲機制。
因為一般方法無法直接獲取到視頻源,所以我們需要使用 Selenium
來模擬瀏覽器操作,從而繞過反爬蟲機制。Selenium 可以模擬真實用戶的行為,如點擊和滾動,以觸發 JavaScript 的執行並獲取動態加載的內容。
透過使用 Chrome 的開發者工具直接看我們要下載視頻 (https://ivod.ly.gov.tw/Play/Clip/300K/153887) 的html 結構發現,該視頻元素的源地址是一個 Blob URL ,要了解 blob URL 本身並不是視頻文件的直接來源,而是一個臨時的 URL,它指向在瀏覽器中存儲的一個對象。這意味著我們無法直接從 blob URL 下載視頻,而需要透過其他方法來獲取實際的視頻數據。這通常需要分析網頁上的 JavaScript 代碼或使用網路請求監聽工具來找到視頻的實際請求地址。
一樣透過 Chrome 的開發者工具來分析視頻是如何被加載的,在source
-> ivod.ly.gov.tw
-> script
-> play.js
:
canAutoplay.video().then(function(o) {
var cap = o.result === true;
_player = new Clappr.Player({
source: _filelink,
parentId: '#fPlayer',
width: _rtspW,
height: _rtspH,
autoPlay: cap,
plugins: [
PlaybackRatePlugin
],
playbackRateConfig: {
defaultValue: 1,
options: [
//{value: 0.25, label: '0.25x'},
{value: 0.5, label: '0.5x'},
{value: 0.75, label: '0.75x'},
{value: 1, label: '1x'},
//{value: 1.25, label: '1.25x'},
{value: 1.5, label: '1.5x'},
//{value: 1.75, label: '1.75x'},
{value: 2, label: '2x'},
],
// rateSuffix: 'x',
},
});
settingPlayer();
});
發現視頻播放器的源地址是通過 _filelink
變量設置的。如果我們想使用 Python 和 Selenium 捕獲實際的視頻源(_filelink 變量),我們需要進一步模擬瀏覽器操作以解析和取得視頻文件的 URL。可以使用 Selenium 執行 JavaScript 代碼來獲取這個變量的值:
filelink = driver.execute_script("return _filelink;")
print("視頻源地址:", filelink)
直接觀察視頻源地址,可以發現這是一個 HLS (HTTP Live Streaming) 格式的播放列表文件(m3u8)。使用 ffmpeg
可以有效地下載這種格式的視頻。確保你已經在各個操作系統上安裝了 ffmpeg
。
ffmpeg
首先,在終端機中執行以下命令來檢查是否已安裝:
ffmpeg -version
如果這個命令返回了版本信息,這意味著 ffmpeg
已經安裝。如果沒有,則需要安裝它。根據使用者的操作系統,安裝方法會有所不同:
MacOS: 使用 Homebrew 安裝:
brew install ffmpeg
Windows:
C:\Program Files\ffmpeg
。ffmpeg
目錄下的 bin
目錄添加到你的系統環境變數 PATH 中。Linux: 通常可以使用包管理器安裝,如在 Ubuntu 上:
sudo apt update
sudo apt install ffmpeg
如果 ffmpeg
已經安裝但不在你的系統路徑中,你可以在 Python 腳本中指定 ffmpeg
可執行文件的完整路徑。修改你的 Python 腳本中調用 ffmpeg
的部分,如下所示:
ffmpeg_path = '/path/to/your/ffmpeg' # 替換成你的 ffmpeg 安裝路徑
command = [
ffmpeg_path,
'-i', m3u8_url,
'-c', 'copy',
'-bsf:a', 'aac_adtstoasc',
output_filename
]
確保將 /path/to/your/ffmpeg
替換為實際的路徑。
以下是整個流程的 Python 腳本示例:
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
import time
import subprocess
# 設定瀏覽器驅動和選項
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--no-sandbox')
options.add_argument('start-maximized')
options.add_argument('disable-infobars')
options.add_argument('--disable-extensions')
# 初始化 Selenium 驅動
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
# 設定輸出文件名
output_file = "downloaded
Uploading downloaded_video.mp4…
_video.mp4"
# 下載視頻
def download_video(m3u8_url, output_filename):
command = [
'ffmpeg',
'-i', m3u8_url,
'-c', 'copy',
'-bsf:a', 'aac_adtstoasc',
output_filename
]
try:
subprocess.run(command, check=True)
print(f"視頻已成功下載至:{output_filename}")
except subprocess.CalledProcessError as e:
print(f"錯誤:{e}")
# 獲取視頻源地址
def get_video_source():
# 訪問網頁
driver.get('https://ivod.ly.gov.tw/Play/Clip/300K/153887')
# 給網頁加載留出時間
time.sleep(10) # 等待 JavaScript 加載
# 執行 JavaScript 代碼來獲取 _filelink 變量的值
filelink = driver.execute_script("return _filelink;")
print("視頻源地址:", filelink)
driver.quit()
return filelink
# 頻源地址
m3u8_url = get_video_source()
if m3u8_url:
# 下載視頻
download_video(m3u8_url, output_file)
# 關閉瀏覽器
driver.quit()
took 5hrs done
實作目標:
使用爬蟲抓取詳細議案資料並下載影片文件。
方法:
修改爬蟲腳本,使其能夠進入每個議案的詳細頁面並根據抓取到的下載鏈接下載影片文件。 使用 Requests 庫進行影片文件的下載。 抓取並保存每個議案的詳細資料及影片。
驗證:
執行爬蟲腳本,確認影片文件可以成功下載並保存到本地或數據庫。