LoginSignup
4
7

More than 1 year has passed since last update.

Pythonで動画をダウンロードするプログラムを作った話

Last updated at Posted at 2022-06-20

今回は…

youtubeの動画を1チャンネルまるごとダウンロードするプログラムを紹介します。

プログラム

今回使うモジュール
pytube
pandas
datetime
youtube api

モジュールダウンロード
pip install _________
python3 -m pip install __________

まずは、ダウンロードするチャンネルの動画ID等を用意します

input.py
import pandas as pd
from apiclient.discovery import build
from apiclient.errors import HttpError

API_KEY = '******************' #伏せてあります、使うときは、api keyを取得すること
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
CHANNEL_ID = '********' #ここもちゃんと入れてね(チャンネルID)
channels = [] #チャンネル情報を格納する配列
searches = [] #videoidを格納する配列
videos = [] #各動画情報を格納する配列
nextPagetoken = None
nextpagetoken = None

youtube = build(
    YOUTUBE_API_SERVICE_NAME, 
    YOUTUBE_API_VERSION,
    developerKey=API_KEY
)

channel_response = youtube.channels().list(
    part = 'snippet,statistics',
    id = CHANNEL_ID
    ).execute()
  
for channel_result in channel_response.get("items", []):
    if channel_result["kind"] == "youtube#channel":
        channels.append([channel_result["snippet"]["title"],channel_result["id"]])

while True:
    if nextPagetoken != None:
        nextpagetoken = nextPagetoken

    search_response = youtube.search().list(
      part = "snippet",
      channelId = CHANNEL_ID,
      maxResults = 50,
      order = "date", #日付順にソート
      pageToken = nextpagetoken #再帰的に指定
      ).execute()  

    for search_result in search_response.get("items", []):
        if search_result["id"]["kind"] == "youtube#video":
            searches.append(search_result["id"]["videoId"])

    try:
        nextPagetoken =  search_response["nextPageToken"]
    except:
        break
   
for result in searches:
    video_response = youtube.videos().list(
      part = 'snippet,statistics',
      id = result
      ).execute()

    for video_result in video_response.get("items", []):
        if video_result["kind"] == "youtube#video":
            videos.append([video_result["snippet"]["title"],video_result["id"]])  

videos_report = pd.DataFrame(videos, columns=['title', 'id'])
videos_report.to_csv("movielist.csv", index=None)

やっていること

  1. youtube apiを読み込み
  2. チャンネルIDを取得し、動画名と動画IDを取得
  3. 取得したものを、csvに保存

そして次に、ダウンロード作業です

download.py
#いろいろimport
from __future__ import unicode_literals
from pytube import YouTube
import pandas
import datetime

channel_name = "*******" #チャンネル名(保存したいフォルダーの名前となるため、何でも良い)
dir_name = channel_name #フォルダー名

with open(f"{channel_name}-download-log.log","w",encoding="utf-8")as log: #新規ログ作成(開始ログ)
    dt_now = datetime.datetime.now() #今の日付・時間を取得
    log.write(f"start: {dt_now.strftime('%Y/%m/%d/ %H:%M:%S')}\n\n") #日付・時間と、開始をお知らせ

deta = pandas.read_csv("movielist.csv",encoding="utf-8")["id"] #ダウンロードする動画のリスト(csv)を読み込む
url = [f"https://www.youtube.com/watch?v={a}" for a in deta] #ダウンロードするurlをリスト化する
print(url) #urlを一旦表示

error = 0
finish = 0

for i in url:
    try: #ダウンロード作業のため、try文でダウンロードエラーを弾く
        yt = YouTube(i)
        yt.streams.filter(
            progressive=True,
            file_extension='mp4'
            ).first().download(output_path=f"{dir_name}/") #ダウンロード(mp4形式、指定したフォルダーに入れる)
        
        print(f"log: download finished - id: {i}") #ダウンロード終了&成功をお知らせ
        
        with open(f"{channel_name}-download-log.log","a+",encoding="utf-8")as log: #ログに追記(ダウンロード成功ログ)
            dt_now = datetime.datetime.now() #今の日付・時間を取得
            log.write(f"{dt_now.strftime('%Y/%m/%d/ %H:%M:%S')} download finished - id: {i}\n") #日付と結果と動画urlを追記する
            
        finish += 1 #正常終了カウントを+1する
    except:
        print(f"log: error download ended - id: {i}") #ダウンロード終了&失敗をお知らせ
        
        with open(f"{channel_name}-download-log.log","a+",encoding="utf-8")as log: #ログに追記(ダウンロード失敗・エラーログ)
            dt_now = datetime.datetime.now() #今の日付・時間を取得
            log.write(f"{dt_now.strftime('%Y/%m/%d/ %H:%M:%S')}: error download ended - id: {i}\n") #日付と結果と動画urlを追記する
            
        error += 1 #エラーカウントを+1する

with open(f"{channel_name}-download-log.log","a+",encoding="utf-8")as log: #ログに追記(終了ログ、ダウンロードのエラー数・成功数も書いておく)
    dt_now = datetime.datetime.now() #今の日付・時間を取得
    log.write(f"\nfinish: {dt_now.strftime('%Y/%m/%d/ %H:%M:%S')}\nfinish count: {finish} error count: {error}") #日付と結果を追記する

やっていること(プログラムのコメントを見れば9割分かると思います)

  1. csv読み込み
  2. 動画idにある動画をダウンロード
    です。
    あと今回は、logも残すようにしています。

まとめ

今回は、youtubeの動画をダウンロードしました。
また、いろいろとpythonを楽しんで行きたいですね^^

ご視聴ありがとうございました!

4
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7