【YouTube】YouTubeの動画をダウンロードする方法その2
以前僕は”やっとYouTubeの動画が保存されている場所を見つけた!”ってツイートしたんですが、
動画が見れるリンクに飛べるものと、403でリンクに飛べないものがあることが判明しました。
違いはわからないんですがまたあとで調べていきたいと思います。
とりあえず今回はおまけ、ということでやり方だけ書いておきます。
やっとYoutubeに上げられてる動画のURLがわかったぞ!
— のぎ@python系男子 (@htmllifehack) 2019年1月11日
音声は余裕だったけど動画は見つけるのは大変だったわ#YouTube
※はじめに言っておきますがこれから紹介する方法は全て自己責任でお願いいたします。損害が発生しても当サイトでは一切責任を負いません。
ソースから動画のリンクを探す
やり方は、まずダウンロードしたい動画のページでソースを開きます。
だいたい右クリックでページのソースを表示を選択するかctrl+Uあたりで表示できます。
そうするとこんな感じのHTMLとjavascriptの画面が表示されます。
このどこかに動画を再生させるスクリプトがあり、そこに動画が保存されているURLが書かれています。
目視では難しいので検索を利用します。
ctrl+Fで検索ウインドウが出るのでそこでitagと入力し検索します。
itagだけだとたくさん検出されるのでもう少し絞り込みます。
ここに書かれたURLはパーセントエンコーディングされているため、例えばitag=22はitag%3d22というように文字が変換されています。
イコール(=)はパーセントエンコーディングすると%3dで表されるということです。
実はURLには使ってはいけない文字列が存在します。
日本語とかがその例です。
なので下のように”%数字アルファベット”という組み合わせを使って他の文字を表しています。
https%3A%2F%2Fr3---sn-3qqp-pcgs.googlevideo.com%2Fvideoplayback%3Fratebypass%3Dyes%26ipbits%3D0%26itag%3D22%26mm%3D31%252C29%26ip%3D240f%253Ae3%253A8d6f%253A1%253Ae9bf%253Ae877%253A1f31%253Aa5ae%26mv%3Dm%26mt%3D1547662666%26ms%3Dau%252Crdu%26pl%3D45%26lmt%3D1543661102125294%26dur%3D59.814%26id%3Do-AE_uQqtWdX6FTEXpEK4mDoeSLbioofnXCr9mRO-wSM5y%26c%3DWEB%26expire%3D1547684332%26ei%3DjHU_XJqVLImDrQTBnYugCA%26key%3Dyt6%26mime%3Dvideo%252Fmp4%26source%3Dyoutube%26txp%3D2211222%26fvip%3D3%26initcwndbps%3D747500%26mn%3Dsn-3qqp-pcgs%252Csn-oguesnz6%26signature%3D1729B5D798E0CD59DB2EB5FACEB5E4923C5DBF9D.CC813786B4948546972F9F4A52574C82A152CEE2%26sparams%3Ddur%252Cei%252Cid%252Cinitcwndbps%252Cip%252Cipbits%252Citag%252Clmt%252Cmime%252Cmm%252Cmn%252Cms%252Cmv%252Cpl%252Cratebypass%252Crequiressl%252Csource%252Cexpire%26requiressl%3Dyes\u0026type=video%2Fmp4%3B+codecs%3D%22avc1.64001F%2C+mp4a.40.2%22,quality=medium\u0026itag=43\u0026urlこの上にある文字列を直接貼ってもURLと認識されないので元の文字列に戻す必要があります。
試しにitag%3dで検索かけてみてください。
これでも数が多いのでさらに絞ります。
itag=〇〇の数字は動画の画質によって異なるのでpytubeで調べることをお勧めします。
とりあえず720pなら22、1080pなら137だけわかればいいかも。
そこでpythonのurllibを使ってデコードします。
エンコードデコードできるサイトもありますがうまくできなかったのでpythonを使いました。
urllibでデコードする
urllibにはurlを解析するためのモジュールが用意されています。
▼urllibドキュメント 21.8. urllib.parse — URL を解析して構成要素にする — Python 3.6.5 ドキュメント
ってことで使っていきます。
import urllib s = "https%3A%2F%2Fr3---sn-oguesnz6.googlevideo.com%2Fvideoplayback%3Fmm%3D31%252C29%26fvip%3D3%26txp%3D2211222%26initcwndbps%3D787500%26itag%3D22%26mime%3Dvideo%252Fmp4%26c%3DWEB%26lmt%3D1543661102125294%26expire%3D1547630839%26dur%3D59.814%26pl%3D16%26source%3Dyoutube%26ms%3Dau%252Crdu%26ei%3Dl6Q-XOPLHM704AK33b-wBQ%26id%3Do-ADCl27Wn9icvLCQieYCJOCsUyGwJto2rNQowvNnwgdW7%26mv%3Dm%26mt%3D1547609083%26ratebypass%3Dyes%26ipbits%3D0%26mn%3Dsn-oguesnz6%252Csn-oguelnle%26sparams%3Ddur%252Cei%252Cid%252Cinitcwndbps%252Cip%252Cipbits%252Citag%252Clmt%252Cmime%252Cmm%252Cmn%252Cms%252Cmv%252Cpl%252Cratebypass%252Crequiressl%252Csource%252Cexpire%26signature%3D214626CFD7F9F9990B6B8F8DED14CAB8305BFC72.9387716E9EB31947F9CB76B080C9192D0F825CB7%26requiressl%3Dyes%26key%3Dyt6%26ip%3D126.141.192.196,type=video%2Fwebm%3B+codecs%3D%22vp8.0%2C+vorbis%22\u0026quality=medium\u0026itag=43\u0026url=" url = urllib.parse.unquote(s) print(url)
このやり方はjupyter notebookだとうまく動くんですがローカルでやるとparseなんてないよってエラーがでます。
その場合はimport urllib.parseで先にインポートしてやってください。
それ以降は同じで大丈夫です。
out: https://r3---sn-oguesnz6.googlevideo.com/videoplayback?mm=31%2C29&fvip=3&txp=2211222&initcwndbps=787500&itag=22&mime=video%2Fmp4&c=WEB&lmt=1543661102125294&expire=1547630839&dur=59.814&pl=16&source=youtube&ms=au%2Crdu&ei=l6Q-XOPLHM704AK33b-wBQ&id=o-ADCl27Wn9icvLCQieYCJOCsUyGwJto2rNQowvNnwgdW7&mv=m&mt=1547609083&ratebypass=yes&ipbits=0&mn=sn-oguesnz6%2Csn-oguelnle&sparams=dur%2Cei%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cexpire&signature=214626CFD7F9F9990B6B8F8DED14CAB8305BFC72.9387716E9EB31947F9CB76B080C9192D0F825CB7&requiressl=yes&key=yt6&ip=126.141.192.196,type=video/webm;+codecs="vp8.0,+vorbis"&quality=medium&itag=43&url=
これだとリンクが無効になってしまいます。
ここで思い出して欲しいのはこのurlはJavaScriptの中に書かれているってことです。
JavaScriptは ; で締めます。
このurlの中に ; が存在するのでsplitを使って分割します。
s = "https%3A%2F%2Fr3---sn-oguesnz6.googlevideo.com%2Fvideoplayback%3Fmm%3D31%252C29%26fvip%3D3%26txp%3D2211222%26initcwndbps%3D787500%26itag%3D22%26mime%3Dvideo%252Fmp4%26c%3DWEB%26lmt%3D1543661102125294%26expire%3D1547630839%26dur%3D59.814%26pl%3D16%26source%3Dyoutube%26ms%3Dau%252Crdu%26ei%3Dl6Q-XOPLHM704AK33b-wBQ%26id%3Do-ADCl27Wn9icvLCQieYCJOCsUyGwJto2rNQowvNnwgdW7%26mv%3Dm%26mt%3D1547609083%26ratebypass%3Dyes%26ipbits%3D0%26mn%3Dsn-oguesnz6%252Csn-oguelnle%26sparams%3Ddur%252Cei%252Cid%252Cinitcwndbps%252Cip%252Cipbits%252Citag%252Clmt%252Cmime%252Cmm%252Cmn%252Cms%252Cmv%252Cpl%252Cratebypass%252Crequiressl%252Csource%252Cexpire%26signature%3D214626CFD7F9F9990B6B8F8DED14CAB8305BFC72.9387716E9EB31947F9CB76B080C9192D0F825CB7%26requiressl%3Dyes%26key%3Dyt6%26ip%3D126.141.192.196,type=video%2Fwebm%3B+codecs%3D%22vp8.0%2C+vorbis%22\u0026quality=medium\u0026itag=43\u0026url=" url = urllib.parse.unquote(s).split(';')[0] print(url)
このurlが動画の元になっています。
まとめ
ソースから解析することで元の動画のリンクが見つかります。
そうすると以前の記事で書いたような動画データと音声データの結合なんて手間はいらなくなります。
残念ながら動画のページに行けるものと行けないものがあるとは思いもしませんでしたが。
試したことは、1080pと720pの画質でやってみたけどダメで、拡張子がmp4とwebmの違いかなって思ったけどこれも両方ともダメ。
なんなんですかね?
違いを探す言うても目視はきびしいもんがあるんでやらないんですけどもしかしたらそのうち偶然違いを見つけることができるかもしれません。
ってことでpytubeが使えるならpytube最強です!
ありがとうございました。