youtubeチャンネルの全動画をpythonとGASでスプレッドシートに出力

youtube

以前youtubeAPIからチャンネルを指定し公開中の動画を取得するスクリプトを書いたんですが、APIの仕様上すべての動画を完全に取得する事が難しい事が分かりました。

さらに、APIを使うと面倒な制約があったり微妙に挙動が不安定だったりとイマイチだったので、何か他に動画一覧を取得する方法がないかなと考えていたんですが、ようやく気付きました。

youtubeチャンネルのhtmlをpythonで正規表現しちゃえばいいじゃないの!(力技)

完成した手順はこんな感じ

youtubeチャンネルの全動画を完璧に取得する方法

チャンネル毎に1回しかやらない作業にスクリプトを書こうと思っていた事がナンセンスでしたね|д゚)

特定チャンネルの動画一覧が欲しい(そもそも)

何がしたいかっちゅうと、チャンネル毎の動画リストが欲しかったんですよね。用途は様々ですが自分のチャンネルの動画を管理したり、他人の動画を分析したり、有名チャンネルのネタをパクったりとか便利ですよね笑

長く続けているチャンネルだと動画が数千件とかあるんで、このデータを簡単にごっそり取得する方法を考えていたんですが「データ取得はAPI」と思い込んでしまっており、大量の動画データをどうにか効率的にyoutubeAPIから取得できないものかと長いこと考えていたんですが、そんなもん必要ない!と気付くのにずいぶん時間がかかってしまいました(*´з`)

youtubeのまとめサイトとか作りたい人は専用プラグインも作ってますんで、必要であれば参考にして下さい。

レシピ

全動画情報の抜き出し作業に必要な材料はこちら。

  • googleクローム(他のブラウザは使った事がないので未検証です)
  • チャンネルURL
  • クローム拡張機能「自動スクロール
  • 動画リンク抜き出し用のpythonスクリプト
  • googleスプレットシート
  • youtubeAPIから動画情報を取得するGASスクリプト

チャンネルページのHTMLを確認

まずは動画リストを取得したいチャンネルページを開きまして動画タブをクリックします。

すると公開中の動画一覧が表示されます、これが全件動画リストです、発見!

動画IDさえ分かればyoutubeAPIのvideoリソースで詳細な動画情報は後でいくらでも肉付け出来ますんで、とりあえずデベロッパーツールで動画IDを探します。

一番最近の動画を開いて動画IDを確認しチャンネルの動画一覧ページのhtmlコードを検索すると、4ヶ所動画IDが記述されている部分がありました。今回はサムネイルURLから動画IDを取得してみます、4ヶ所の内サムネイルURLを選択したのは理由はありません笑、最初に見えただけだと思います。

他の部分を選んでも正規表現を書く手間とか変わらないので、どこから動画IDを取得しても特に優劣はない気がします。

とりあえず動画一覧が表示されているページから動画IDがごっそり取れそうなのは確認できました。

最古の動画が現れるまで延々と下にスクロールする

ただ大きな問題がありまして、youtubeは端末のファーストビュー部分にしか動画(html)を表示しておらず、下までスクロールする事で次の一覧を動的に読み込む仕組みになっています。

つまりすべての動画IDをhtmlコード上に表示させるには最古の動画まで延々とスクロールをする必要があるという事です!面倒くさいけど。

自分の指に自信がある方はマウスのホイールを無限にクリクリすればいいんですが、僕みたいな面倒くさがりの人は「自動スクロール」というクローム拡張機能があるのでオススメです。

ポインタを矢印に合わせるだけで勝手に上下にスクロールしてくれます、一番下に行きつくまでは放置して休憩タイムにしましょう(‘ω’)

最古の動画を掘り当てました、若いですねぇ~笑

すべての動画IDが詰まっている親階層を.txtへコピー

最古の動画までスクロールした事でhtmlコードにはすべての動画が表示されている状態です、後はズバッと全部コピーして.txtファイルに貼り付けます。

デベロッパーツールのelementsをコピーするには該当の要素をすべて含む親要素をctrl+cでクリップボードにコピーできます。

後は.txtファイルを適当に作って張り付け。

132,369行のコピペなので結構重いです、頑張れパソコン。

pythonの正規表現でhtmlコードから動画リンクを抜き出す

youtubeの動画IDが全件含まれたテキストが手に入ったので、後は好きな言語で正規表現して抜き出すだけです。

ローカルでちょこっと動かすのに便利なので僕はpythonでやりました、スクリプトはめっちゃ簡単にwith openでさっき保存した.txtを読み込み、動画IDをチェックする正規表現をreモジュールの.findallで探す感じです。

スクリプトを書くのが面倒な方は下の方でサンプルコードを公開しています。

python使うならyoutubeチャンネルのスクレイピングコード書けばいいやん?

pythonにはseleniumというブラウザ操作を自動化する便利なライブラリがあるので、上記で解説した動画ページのスクロールとか.txtファイルへのコピペとか全部自動でやらせるスクリプトを書くのも難しくはないです。

ですが、僕は明らかに使用頻度の少ない作業に対してスクリプトを書くのってどうなの?って考えてまして、あまり使わないスクリプトってどういう仕組みで動かしてるか忘れちゃうし、htmlページの仕様なんていつか変わるんであまり好きじゃないんですよね。

さらにyoutubeはスクレイピングを禁止してるらしいので、目を付けられてIPアドレスブロックされるのも面倒だったので動画一覧の取得までは手動で行っています。IPアドレスを偽装して突破する事も難しくないですが、youtubeに嫌われたくないので今回は怒られない方法でやってます(*´з`)

サムネイルURLから動画IDを取得する正規表現

ところで、正規表現を書くのが苦手って人いると思いますがあんまし難しくはないですよ、正規表現が正しいかチェックするツールっていくつもありまして、僕はpythonで正規表現を書く時はpythexを使ってます。

ちょっと横道に逸れて「正規表現の書き方簡易講座」みたいになっちゃいますが、例えば今回のようにサムネイルURLから動画IDを抜き出したい時はこんな手順で僕はやります。

  • https://pythex.org/を開く
  • Your regular expression:とYour test string:にサムネイルのURLを入れる
  • Your regular expression:に張り付けた値に「?」が含まれる場合は直前に\を入れる(正規表現のエスケープ
  • 抜き出したい箇所を()で囲う
  • ()の中を.*?に書き換える
  • 繰り返し同じにならない箇所も.*?に書き換える

これで完成です、動画でみるとこんな感じ。

簡単な正規表現の書き方

前後にも文字が入ると思うので今回は「.*?https://i.ytimg.com/vi/(.*?)/.*?」という感じで正規表現を作ってみました。これでちゃんと動画IDがこんな感じで取れます。

このスクリプトでは抜き出した動画IDを加工して動画リンクの形にしてCSVに出力していますが、動画IDのまま出力する事もできます。

もちろん正規表現の解説は色々端折ってますが、たくさん正規表現を書いて大体この手順で一致するパターンは作れてきたので、これで上手く行かなかったら細かい文字クラスとか調べて制限を増やす感じでいつもやってます。

youtubeAPIのvideoリソースでデータを肉付けする

チャンネルページのHTMLにすべての動画情報が揃っているわけじゃないので、タイトル・再生時間などの必要データはyoutubeAPIのvideoリソースで補完します。

僕はリストとして汎用的に使用したかったのでgoogleスプレットシートにコピペして、動画情報の取得処理はpythonじゃなくてGASで書きました。GASもやっぱり便利だわぁ。

ちなみに上記のスクリプトを定期実行&新着動画も自動で追加するスクリプトも付け加えれば、チャンネル毎の全動画情報を抜けなくスプレットシートで管理できる「youtube動画監視システム(他人のチャンネルでも可能)」が作れたりします、いくつかの会社さんに導入頂いてますんで興味がある方はご連絡下さいm(_ _)m

youtubeAPIのvideoリソースの中身を確認してみる

youtubeAPIキーの取得方法からvideoリソースの中身の確認まで、前回の記事で一通り解説しているので詳しく知りたい方は読んでみて下さい。

GASのタイムアウト制限を突破する

GASは無料で便利なんですが「処理時間が6分を超えると強制終了」されるという制限がありまして、今回のように数千件を超える動画データをまとめて処理しようとすると、必ず制限に引っ掛かり処理が途中で止まります。

並列処理でゴリゴリ動かして処理時間を短くする工夫もあると思いますが、それはそれで負荷の監視とかが面倒なので、今回は普通にタイムアウトになる前に意図的に処理を途中で区切って、その続きからデータ取得処理を再開できる方向で考えてみました。

と言っても下記のような簡単な仕組みです。

  • 1度の処理で500レコード処理する(6分以内で終わるなら何件でもOK)
  • データの肉付けが終わったレコードにはtimestampを付ける
  • timestampの昇順でシートを並び替える(timestampが付いてないレコードが上にくる)
  • timestampが付いてない未処理のレコードがなくなったらreturn

みたいな感じで、後は全部のレコードにデータの肉付けが終わるまで実行ボタンを連打するだけです。

サンプルコード(コピペで動きます)

ここまでで解説した各スクリプトは難しくはないと思いますが、自分で書くのが面倒な方向けに「pythonの正規表現でhtmlコードから動画リンクを抜き出すpythonスクリプト」と「youtubeAPIのvideoリソースでデータを肉付けするGASスクリプト」の各コピペコードを置いておきました。

操作手順を解説する簡単な動画も用意しましたんで必要な方は参考にしてみて下さい。

----▽ ここから有料です ▽----

決済方法 料金 返金 アカウント登録
note.com ¥500 – 購入する 24時間以内 不要
paypal
いつでも 必要

以降のコンテンツは閲覧パスワードを購入された方限定で公開しております。必要な方は上記の購入ボタンより各サイトにてお支払い手続きをお願いしますm(_ _)m

【返金保証付き】記事の内容に不満があれば全額返金します!

記事の内容に満足頂けない場合はお支払い頂いた料金をすべてお返しします。

  • noteよりご購入された場合:note.comにてご確認下さい。
  • paypalよりご購入された場合:お問い合わせより「購入日」と「paypalの取引ID」をご連絡下さい。

有料記事に関するNG行為

  • パスワードを第三者に譲渡する行為
  • 不正に入手したパスワードで有料記事を閲覧する行為

上記のルールを違反した場合は筆者が怒りますので、お気を付けください(゚Д゚;)