上回介紹 Python 新手線上教學資源提到我有在看政大磨課師課程的線上開放課程 - 成為python數據分析達人-的第一門課,課程偏重數據分析演練,挺實用的。

課程是開放的,只要申請個新帳號任何人都可以看課程影片。

實際看了幾篇,發現上操作有點不便。以這堂 Python 課程為例,每一章有多個小節:

每小節標題點進去的頁面如下圖,基本上就是一個內嵌 YouTube 影片播放器,下方則有按鈕可以跳上一節下一節:

正常狀況用網頁看,點放到全螢幕,看完一節縮小再按下一節,倒也還行。但我習慣調快播放速度,每次切到下節會恢復正常速度,需要重新調快;所以我在想,若能做成 YouTube 播放清單,直接在 YouTube App 看,一來不用每次點一下放大能會自動播放下一節,二則播放速度不用每次重調,豈不美哉。

YouTube 可以自訂播放清單,一般人應該就是一節一節點進去開影片加入播放清單就完了;但我可不行,手工操作重複到第三遍,通常就會喚醒我靈魂深處的王藍田,把滑鼠丟到地上用木屐踩,再放到嘴裡咬破吐掉... (謎之聲:這是什麼毛病)。因此,我寧可多花一倍時間寫程式完成它~

我寫了一小段 jQuery + JavaScript 用 F12 跑,先掃出所有 n-n 小節標題對映的 URL,呼叫 fetch 取回該頁 HTML,從中取出 YouTube 內嵌播放器 URL 中的影片代碼,最後產生一個 CSV 自動下載。(嘿,幾十年的全端工程師沒有白幹啊~)

list = jQuery(".aalink[href*='view.php?id=']")
    .filter((i, e) => $(e).text().match(/^[0-9]*-[0-9]*/))
    .map((i, e) => {
        const o = $(e);
        return {
            text: o.text(),
            link: o.attr('href')
        }
    }).get(); 
//list = list.slice(0, 10);
const promises = list.map(item => {
    console.log(item.text, item.link);
    return fetch(item.link)
        .then(response => response.text())
        .then(html => new Promise((resolve, reject) => {
            const m = html.match(/https:\/\/www.youtube.com\/embed\/([^?]+)/);
            if (m) item.youtube = "https://www.youtube.com/watch?v=" + m[1];
            resolve(item);
        }));
});

Promise.all(promises)
    .then(items => {
        const playlist = [];        
        list.filter(item => item.youtube).forEach(item => {
            playlist.push(item.youtube);
        });
        const csvUrl = URL.createObjectURL(new Blob([playlist.join('\n')], { type: 'text/csv' }));
        const downloadLink = document.createElement('a');
        downloadLink.href = csvUrl;
        downloadLink.download = 'playlist.csv';
        downloadLink.click();
    })
    .catch(error => {
        console.error(error);
    });

在課程章節清單網按 F12 跑程式,它會掃瞄出所有小節網頁 URL 再逐一從中抓出 YouTube 影片編號:

醬子,就拿到全部影片的 YouTube 連結了,共 70 筆,估計能省下幾百次點擊操作。

這個 csv 要怎麼轉成 YouTube 播放清單呢?查了一下,YouTube 沒有提供從檔案匯入的功能,要在網頁手工操作。另一條路是用 YouTube Data API,這個副本下次再打。我查到有個 Soundiiz 播放清單管理平台,提供將 CSV 播放清單匯入 YouTube 的功能,上傳 CSV 再授權 Soundiiz 存取你的 YouTube,播放清單就做好囉~

Exploring how to convert an online Python data analysis course into a YouTube playlist using jQuery, JavaScript, and CSV export to streamline video playback and speed adjustments.


Comments

# by jackson18327

耶...你的code 不是python

# by boy

是 Python 線上課程 XD

# by yoyo

怎麼不是用python寫爬蟲 抓取youtube影片清單XD

# by Jeffrey

to yoyo,F12 跑 JavaScript 抓 DOM 最直接省事,爬蟲需額外解決網頁登入問題,資料已垂手可得,用 Python 寫爬蟲的好處應該只剩練功吧?:D

# by gay

import re import requests from bs4 import BeautifulSoup from urllib.parse import urljoin # 取得所有包含 'view.php?id=' 的連結 links = [] for link in soup.select(".aalink[href*='view.php?id=']"): if re.match(r"^\d*-\d*$", link.text.strip()): links.append({ "text": link.text.strip(), "link": urljoin(base_url, link["href"]) }) # 處理每個連結,並抽取 YouTube 影片連結 playlist = [] for item in links: print(item["text"], item["link"]) response = requests.get(item["link"]) html = response.text match = re.search(r"https://www.youtube.com/embed/([^?]+)", html) if match: item["youtube"] = f"https://www.youtube.com/watch?v={match.group(1)}" playlist.append(item["youtube"]) # 將 YouTube 影片連結匯出為 CSV 檔案 import csv from tempfile import NamedTemporaryFile with NamedTemporaryFile("w", delete=False, newline="") as csvfile: writer = csv.writer(csvfile) writer.writerow(playlist) print(f"CSV file saved: {csvfile.name}")

# by Jeffrey

to gay, 上述程式是否省略手動抓 HTML,貼入 Python 程式碼或存檔後讀取, soup = BeautifulSoup(html) 的程序?亦或有其他更省事的做法?(註:清單網頁需登入才能存取)

# by boy

gay 你的 request?

# by student

謝謝分享 剛好最近有這個需求 但打算用 api 的方式來實作 獲取所有播放清單的影片標題 然後資料清洗取得想要的資訊

Post a comment