見出し画像

GASとPhantomJSで日本のYouTubeの急上昇のリストを取得するコードの一部を公開

YouTubeのホームページで毎日15分毎に更新される急上昇動画の一覧をGAS(Google Apps Script)を使用して定期的に取得するプログラムを作りました。

画像7

作成するきっかけ

私はYouTuberの端くれなので、新しいチャンネル作成や投稿する動画のネタをリサーチするために、急上昇のチェックは毎日の日課となっています。

しかし、「急上昇を見る」→「気になる動画を記録する」という手順がどうしても毎日続かなく、どうにか自動取得ができないか模索していました。

これまでもGASを使用してYouTubeリサーチのためのプログラムをいくつか作っていたため、急上昇のリストを自動取得し、取得した結果をリサーチに使うという目的で開発を開始しました。

いろいろ調べながらコーディングしていたのですが、以下の2つの壁にぶち当たりました。プログラミングも趣味程度で行っているレベルのため、解決するために3日(約6時間)もかかってしまいました。今回の記事は、ぶち当たった壁とその解決方法を書きたいと思います。同じような境遇の方に見てほしいです。

今回ぶち当たった壁

①YouTubeの急上昇ページが動的なページである
スクレイピングを行うにあたって、YouTubeのHTMLコードを分析するのですが、動的なページ(JavaScript?)のため、単純な取得ができませんでした。

②PhantomJSで取得すると、アメリカのYouTubeの情報を取得する
①の動的なページの取得を解決するためにPhantomJSというヘッドレスブラウザのサービスを使用しましたが、このサービスを使うとアメリカのYouTubeの情報を取得してしまう。

では詳しく説明いたします。

①YouTubeの急上昇ページが動的なページである

まずこちらがYouTubeの急上昇のページになります。

https://www.youtube.com/feed/trending

画像1

急上昇は「最新」「音楽」「ゲーム」「映画」の4つに分かれています。

このページのコードを見てみます。

画像2

分かりにくいですよね・・・実際に皆さんもブラウザで「ソースの表示」などをやってみてください。

横長でわかりにくい!

スクレイピングなので動画のタイトルやURLなどを検索し、何のタグで囲まれているか等を調べます。例えば「Shohei」で検索すると、ヒットします。

画像3

これは難しくないな、と思いGASのライブラリの「Parser」で取得しようとしても、全然取得できなかったのです。

いろいろ調べると、JavaScript等を使用した動的なページのため、GASのPaeserは対応していないとのこと。

Python+Seleniumで取得する方法はググったら出てきましたが、「GAS スクレイピング」とググると「PhantomJS」が出てきたので早速使ってみました。ちなみにGASにこだわったのは、定期的実行と共有が楽だったのでPythonに逃げずにGASで探していました。

画像4

細かな使用方法は省略しますが、簡単に説明すると・・・

①無料で1日あたり500ページ分の動的なページのコードを返してくれる
②有料プランもあり
③現在は開発終了している

登録も簡単でメールアドレスを入れてパスワードを設定するだけでできました。

早速PhantomJSを使用してコードを書きました。

//ファントムのKEY
var key = "PhantomJSのAPI-KEY";

var payload = 
     {url:eval("取得したいページのURL"),
      renderType:'HTML',
      outputAsJson:true};
 payload = JSON.stringify(payload);
 payload = encodeURIComponent(payload);

 var url = 'https://phantomjscloud.com/api/browser/v2/'+ key +'/?request=' + payload;                

 //急上昇の必要部分をざっくり抽出
 var response = UrlFetchApp.fetch(url);
 var json = JSON.parse(response.getContentText());
 //Contentとdataの間のコードを取得
 var source = json["content"]["data"];

これで実行すると

title="SHOHEI OHTANI CANNOT BE STOPPED! (Shohei ties for the lead league in home runs with 23)" href="/watch?v=R_bG2jGJ1Es" aria-label="SHOHEI OHTANI CANNOT BE STOPPED! (Shohei ties for the lead league in home runs with 23) by MLB 1 day ago 3 minutes, 55 seconds 916,077 views">
           <yt-icon id="inline-title-icon" class="style-scope ytd-video-renderer" hidden=""><!--css-build:shady--></yt-icon>
           <yt-formatted-string class="style-scope ytd-video-renderer" aria-label="SHOHEI OHTANI CANNOT BE STOPPED! (Shohei ties for the lead league in home runs with 23) by MLB 1 day ago 3 minutes, 55 seconds 916,077 views">SHOHEI OHTANI CANNOT BE STOPPED! (Shohei ties for the lead league in home runs with 23)</yt-formatted-string>
         </a>
       </h3>
       <div id="menu" class="style-scope ytd-video-renderer"><ytd-menu-renderer class="style-scope ytd-video-renderer" flexible-menu=""><!--css-build:shady--><div id="top-level-buttons" class="top-level-buttons style-scope ytd-menu-renderer" hidden=""></div>
<div id="top-level-buttons-computed" class="top-level-buttons style-scope ytd-menu-renderer"></div>
<yt-icon-button id="button" class="dropdown-trigger style-scope ytd-menu-renderer" touch-feedback=""><!--css-build:shady--><button id="button" class="style-scope yt-icon-button" aria-label="Action menu">
 <yt-icon class="style-scope ytd-menu-renderer"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope yt-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope yt-icon"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" class="style-scope yt-icon"></path></g></svg><!--css-build:shady--></yt-icon>
</button><yt-interaction id="interaction" class="circular style-scope yt-icon-button"><!--css-build:shady--><div class="stroke style-scope yt-interaction"></div><div class="fill style-scope yt-interaction"></div></yt-interaction></yt-icon-button>
</ytd-menu-renderer></div>
     </div>
     <ytd-video-meta-block class="style-scope ytd-video-renderer"><!--css-build:shady-->
<div id="metadata" class="style-scope ytd-video-meta-block">
 <div id="byline-container" class="style-scope ytd-video-meta-block">
   <ytd-channel-name id="channel-name" class="style-scope ytd-video-meta-block"><!--css-build:shady--><div id="container" class="style-scope ytd-channel-name">
 <div id="text-container" class="style-scope ytd-channel-name">
   <yt-formatted-string id="text" title="" class="style-scope ytd-channel-name complex-string" ellipsis-truncate="" has-link-only_=""><a class="yt-simple-endpoint style-scope yt-formatted-string" spellcheck="false" href="/c/MLB" dir="auto">MLB</a></yt-formatted-string>
 </div>
 

このように取得できるので、あとはタグを解析して必要な情報を取るだけになります。今回は動画の名前やID、URL等を取得しました。

このようにしてYouTubeの急上昇の動的なページを取得する、という壁を突破しました。

②PhantomJSで取得すると、アメリカのYouTubeの情報を取得する

1つの壁を突破したら、次の壁が待っていました。PhantomJSについてはググったらいくつも記事が出てきて、参考にできましたが、この問題はググっても出てこなくて、何度もトライ&エラーを繰り返し、見つけ出しました。おそらく記事にしているのはこのnoteだけかもしれませんので、貴重な情報です。

上の①のPhantomJSの取得例で「Shohei」が取得できていましたが、これは日本のYouTubeの急上昇になります。これは問題を解決したあとに取得したもです。なにもしないとこうなります。

title="Ariana Grande - pov (Official Live Performance) | Vevo" href="/watch?v=fLFvbwrWLQY" aria-label="Ariana Grande - pov (Official Live Performance) | Vevo by Ariana Grande 19 hours ago 3 minutes, 15 seconds 3,393,386 views">
           <yt-icon id="inline-title-icon" class="style-scope ytd-video-renderer" hidden=""><!--css-build:shady--></yt-icon>
           <yt-formatted-string class="style-scope ytd-video-renderer" aria-label="Ariana Grande - pov (Official Live Performance) | Vevo by Ariana Grande 19 hours ago 3 minutes, 15 seconds 3,393,386 views">Ariana Grande - pov (Official Live Performance) | Vevo</yt-formatted-string>
         </a>
       </h3>
       <div id="menu" class="style-scope ytd-video-renderer"><ytd-menu-renderer class="style-scope ytd-video-renderer" flexible-menu=""><!--css-build:shady--><div id="top-level-buttons" class="top-level-buttons style-scope ytd-menu-renderer" hidden=""></div>
<div id="top-level-buttons-computed" class="top-level-buttons style-scope ytd-menu-renderer"></div>
<yt-icon-button id="button" class="dropdown-trigger style-scope ytd-menu-renderer" touch-feedback=""><!--css-build:shady--><button id="button" class="style-scope yt-icon-button" aria-label="Action menu">
 <yt-icon class="style-scope ytd-menu-renderer"><svg viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet" focusable="false" class="style-scope yt-icon" style="pointer-events: none; display: block; width: 100%; height: 100%;"><g class="style-scope yt-icon"><path d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z" class="style-scope yt-icon"></path></g></svg><!--css-build:shady--></yt-icon>
</button><yt-interaction id="interaction" class="circular style-scope yt-icon-button"><!--css-build:shady--><div class="stroke style-scope yt-interaction"></div><div class="fill style-scope yt-interaction"></div></yt-interaction></yt-icon-button>
</ytd-menu-renderer></div>
     </div>
     <ytd-video-meta-block class="style-scope ytd-video-renderer"><!--css-build:shady-->
<div id="metadata" class="style-scope ytd-video-meta-block">
 <div id="byline-container" class="style-scope ytd-video-meta-block">
   <ytd-channel-name id="channel-name" class="style-scope ytd-video-meta-block"><!--css-build:shady--><div id="container" class="style-scope ytd-channel-name">
 <div id="text-container" class="style-scope ytd-channel-name">
   <yt-formatted-string id="text" title="" class="style-scope ytd-channel-name complex-string" ellipsis-truncate="" has-link-only_=""><a class="yt-simple-endpoint style-scope yt-formatted-string" spellcheck="false" href="/channel/UC9CoOnJkIBMdeijd9qYoT_g" dir="auto">Ariana Grande</a></yt-formatted-string>
 </div>
 

コードではわかりにくいので、キャプチャを。

画像5

アリアナグランデ!
そう、アメリカのYouTubeの急上昇のリストを取得しているんですよね。
(19時間で339万回再生はやばい・・・)
すぐに気づかなかったのですが、おそらくPhantomJSはアメリカのサーバーを使用しているので、アメリカの結果がでるのだと仮定しました。

ちなみにURLは同じ「https://www.youtube.com/feed/trending」です。アクセスする地域によって、結果が地域ごとに変わるようですね。

「日本にいながら、アメリカの急上昇を見る」ことは、YouTubeの設定で変更することは可能です。

画像6

YouTubeの設定の「場所」を見たい国に変更することができます。
しかし、URLはどの国も一緒なのです。
国ごとに異なる結果が変えてくるので、絶対になにか対策はあると考え、試行錯誤をした結果、見つけました。

国を選択すると、一瞬(ほんの0.3秒くらい?)URLに変化があることを知りました。そこで一瞬表示されるURLをキャプチャを取って、打ち込むことによって解決することができました。

//PhantomJSを通すと、必ずアメリカの急上昇となる
https://www.youtube.com/feed/trending
//URLの後ろに &persist_gl=1&gl=JP を付けることにより、日本の情報を取得できた
https://www.youtube.com/feed/trending&persist_gl=1&gl=JP

URLの後ろに「&persist_gl=1&gl=JP」を入れることで、日本の情報を取得するコードが必要だったのですね。

ということで解決に至ったわけです。

おかげさまで急上昇の「最新」「音楽」「ゲーム」「映画」の4つ(映画はリサーチに不要だったので結果省きました)を取得するコーディングを行い、無事定期的な取得するプログラムを作ることができました。

さいごに

今回の記事は「動的なページを取得」「PhantomJSで取得するデータ」の課題の解決方法をまとめました。おかげでリサーチの効率化を図ることができました。

またURLで国を指定することができるため、いまは日本の急上昇を取得していますが、YouTubeが展開している世界中の急上昇情報を取得することも可能となりました。

アメリカのYouTubeで流行ったことは時を経て日本で流行ることが多くわかっています。また、台湾や韓国、タイ等アジア圏の流行りを知ることによって、動画のネタを考える際の参考にもなります。

今回のツールはYouTubeリサーチにとって有益なツールとなると思っています。

まだ配布可能な状態にしておりませんが、コードの整理やマニュアルの整備を行ったら数量限定で配布したいと思います。

※ツイッターでYouTubeの事や開発についてたまにつぶやいています。

画像8


この記事が気に入ったらサポートをしてみませんか?