アルバイトのMoriです。

世の中にはたくさんのWebサービスがありますが、そのサービスを利用するだけではなく、サービスでどのような通信が流れ、JavaScriptが実行され、最終的にコンテンツが出来上がっているかを逆算で読み解いているエンジニアさんたちもいます。完成品から内部構造を逆算的に読み解くことは、俗にリバースエンジニアリングと呼ばれます。

今回は、こちら「Reverse-engineering YouTube | Alexey Golub」のサイトを補足・解説する形で、題材として「Youtubeのチャンネルに投稿されている動画のdescription(概要欄)を取得する」というテーマでリバースエンジニアリングを解説してみたいと思います。

投稿動画のvideoIdを取得

動画のメタデータを取得するためには、最初に動画のvideoIdを取得する必要があります。一番簡単な方法はチャンネルトップページの動画タブにアクセスすることです。curlリクエストで再現する場合の形式は以下のようになります。
curl https://www.youtube.com/channel/{channelId}/videos \
-H 'User-Agent:{userAgent}' 
レスポンスのHTMLドキュメントにはレンダリング用のオブジェクトwindow["ytInitialData"]があります。これには投稿日時が若い動画の情報が格納されています。
  • 動画のvideoId
  • この後のリクエストに必要なパラメータcontinuation
先ほど取得した動画よりも投稿日時が古い動画を取得するために、ページをスクロールすると裏側で流れるリクエストを叩きます。curlリクエストで再現する場合の形式は以下のようになります(ヘッダの値は適宜変更してください)。
curl https://www.youtube.com/browse_ajax?continuation={continuation} \
-H 'X-Youtube-Client-Version:2.20190830.05.01' \
-H 'X-Youtube-Client-Name:1'
レスポンスからvideoIdcontinuationが取得できます(ただし、これ以上古い動画がない場合にはcontinuationは存在しません)。以上の操作をcontinuationの値を更新しながら繰り返すことで全動画のvideoIdを取得することができます。

動画のメタ情報を取得

先ほどの節でvideoIdの取得が完了しました。この節ではvideoIdから動画のメタデータを取得する方法について解説します。動画のメタデータを取得する方法としてYoutubeが提供しているiframeのAPI内部で使用されているエンドポイントを利用します。curlリクエストで再現する場合の形式は以下のようになります。
curl https://www.youtube.com/get_video_info?video_id={videoId}&hl=ja
レスポンス内の動画メタデータはURLエンコードされているため、まずデコードする必要があります。さらにメタデータのフィールドは&で繋げられているため、&で区切ってから利用すると良いでしょう。そうして取得したメタデータからplayer_responseフィールドの値(JSON形式)を取り出します。ここには動画の概要欄などの情報が含まれます。 これまで述べた方法でチャンネルの動画の概要欄が取得できます。

最後に

ここでご紹介したのはあくまでどのようにWebサービスの通信を読み解くかという考え方のご説明でした。多数のリクエストを伴う場合サービスへの迷惑となる可能性もありますので、極力サービスが提供するAPIなどの正規の手段を用いるようにしてください。

参考になったページ