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

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

プログラム
---
今回使うモジュール
``pytube``
``pandas``
``datetime``
``youtube api``

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

まずは、ダウンロードするチャンネルの動画ID等を用意します
```python: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を読み込み
1. チャンネルIDを取得し、動画名と動画IDを取得
1. 取得したものを、csvに保存

そして次に、ダウンロード作業です
```python: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読み込み
1. 動画idにある動画をダウンロード
です。
あと今回は、logも残すようにしています。

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

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