YouTubeコメントを自動&スクロールなしで読めるスクリプトを作ってみる

JavaScript

YouTubeでコメントを読む際、スマホならアプリを使えば動画を見ながらコメントをみることができますが、PCでブラウザからYouTubeをみているときはそれができません。

コメントをみるためにスクロールしたら動画も一緒にスクロールされるので見れなくなります。

コメントをスクロールなしで確認する方法はないのだろうか?

コメントをスクロールなしでみることができれば、動画をみながらコメントも確認できます。

なんかいい方法はないかと思って考えてたらひらめいたのでスクリプトを作ってみることにしました。

 

どんなものを作ったかはテキストだと説明が難しいので動画をご覧ください。

YT Comment Reader (without scroll) + Auto Loader

どうでしょうか?ちゃんと動画を画面内に含めたままコメントを読むことができています。

 

見た感じコメントを表示するだけのスクリプトにみえるかもしれませんが、そうではありません。

YouTubeは不要なサーバー負荷を抑えるため、一度に読み込まれるコメント数が制限されています。

なので自動でコメントを随時読み込んでいく機能も必要です。

そういう話も込みで、今回スクリプトを作った手順を紹介していきたいと思います。

スポンサーリンク

コメントを取得する

コメントをスクロールなしで表示するためには上の動画でもやっていたようにトースターを使ってコメント文を表示すればよいのですが、コメント文を取得しなければなりません。

 

Google開発者ツールでタグを確認してみると動画へのコメントは以下のような規則性がみられました。

<yt-formatted-string id="content-text" slot="content" split-lines="" class="style-scope ytd-comment-renderer">
    コメント内容
</yt-formatted-string>

なので、ここから中身の文を取り出せばそれがコメント文になります。

 

中身を取り出すのは至って簡単。今回はidを使って取り出します。

document.querySelectorAll("[id^=content-text]")[0].innerText

getElementByIdだと複数取り出せないのでquerySelectorAllを使っています。

[0]の部分を変数にして+1ずつしていけば上から順番にコメントを取り出せます。[0]は1番目のコメント。[1]は2番目のコメント・・・といったかんじ。

 

idを指定してコメントを取得できましたが、実はyoutubeは他の部分にも同じidを使っています。そのため、コメント以外が取得されてしまうのを回避するためif文を書きます。

if (document.querySelectorAll("[id^=content-text]")[c].classList[1] == "ytd-post-renderer") return;

YouTubeのコミュニティのメッセージもcontent-textというidが使われているので除外しないと表示されてしまいます。

コメントを自動で読み込む

ここが最も苦労した部分。

コメントを自動で読み込む機能をつけないとコメントの表示が20で終わってしまいます。

YouTubeがサーバーへの負荷を軽減するために一度に読み込まれるコメント数が20に制限されているからです。

 

新たにコメントが読み込まれるタイミングはユーザーが一番下のコメントがある場所までページをスクロールしたときです。

コメントを自動で読み込むには、一番下までスクロールしたときに発火するイベントを強制的に起こすかコメントを読み込む関数を呼び出すしかない

イベントを強制的に起こすのは無理そうだと判断したので、コメントを読み込む関数を呼び出すことにしました。

簡単に言いましたが、これをするということは容易なことではないと気づく方もいらっしゃるかもしれません。(簡単じゃね?と思う人もいるかもしれないけど)

 

とりあえずコメントを読み込む関数を呼び出すことがどういうことか説明。

コメントを読み込む関数はYouTube側のスクリプトに含まれている

つまりYouTube側のスクリプトを解析して関数を探し、書き換えないといけない

しかもページ読み込み時にオリジナルをブロックして書き換えたスクリプトを読み込まないといけない

多分この時点で「あぁ・・・無理だわ」と思う人もいるかもしれませんね。

正直私も無理なんじゃないかと思って1日くらい作るのためらいました。

ただ、自動で実行されるようにYouTube側のスクリプトを書き換えることさえできれば完成なので頑張ってみることにしました。

YouTube側のスクリプトを解析

どうやったのかは省きますが、結果はdesktop_polymer_v2.jsに書いてあるonRetrieveLocation_という関数を呼ぶとコメントが読み込まれることがわかりました。

これを書き換えて35秒ごとに自動で呼び出されるようにしました。

onRetrieveLocation_:function(a,b){
     if (window.loadTimeout) clearTimeout(window.loadTimeout);
     window.loadTimeout = setTimeout(() => {
        if (window.enableAutoLoad) this.onRetrieveLocation_(a, b);
     }, 35000);
     b.hasComments?b.locationRetrieved("/comment_service_ajax?action_get_comments=1&pbj=1",void 0):b.locationRetrieved("/related_ajax",void 0);a.stopPropagation()
}

ページ読み込み時に改変したスクリプトを読み込む

desktop_polymer_v2.jsを読み込まれないようにして、改変済みのdesktop_polymer_v2.jsを読み込む必要があります。

そのためにMutationObserverを使います

new MutationObserver(mutations => {
    mutations.forEach(({
        addedNodes
    }) => {
        addedNodes.forEach(node => {
            if (node.nodeType === 1 && node.tagName === 'SCRIPT' && node.src && node.src.includes('desktop_polymer_v2.js')) {
                node.src = "改変後のJavaScriptのURL";
            }
        })
    })
}).observe(document.documentElement, {
    childList: true,
    subtree: true
});

ちなみに書いてませんでしたが、Tampermonkeyでスクリプトを実行することが前提です。MutationObserverを使えばページ読み込み時に読み込まれるスクリプトをブロックしたりスクリプトのURLを書き換えたりできます。

スポンサーリンク

2つの機能をあわせれば完成

  • コメントの内容を取得してトーストで表示する機能
  • コメントを自動で定期的に読み込む機能

この2つをあわせたらスクロールせずにコメントを読むスクリプトの完成です。この2つがあって初めて成り立つものです。

    個人的にはYouTube側のスクリプトを書き換える時点でちょっと難易度高めだと思っています。

    もしフルコードが欲しい方がいたらコメントくれたら渡せるかも・・・。

    コメント

    1. sigma より:

      興味深い内容でした。。githubとかには上げてないですよね。。。

      • HaniCheki より:

        興味を持ってくださりありがとうございます
        残念ながらこのスクリプトは使えなくなってしまいました。(おそらくYouTubeのアップデートで)

        直してもYouTubeのJSに依存するためアプデ毎に使えなくなりそうです。
        せっかく興味持っていただいたのに申し訳ないです・・・

    2. ゆい より:

      こんにちは
      今現在の仕様でスクロール無しでコメント読み込むにはどうしたらいいでしょうか?

      • HaniCheki より:

        こんにちは。

        さきほどちらっと確認してみたらdesktop_polymer.jsに
        onRetrieveLocation_関数が存在していました。

        おそらくアプデされてもその部分は特に変更されていないと思うので
        記事で示したような書き換えをして元のdesktop_polymer.jsの代わりに読み込ませれば可能ではないかと思っています。

    3. ゆい より:

      Tampermonkeyというのはブラウザのコンソールで代替可能でしょうか?

    4. ゆい より:

      onRetrieveLocation_:function(a,b){
      if (window.loadTimeout) clearTimeout(window.loadTimeout);
      window.loadTimeout = setTimeout(() => {
      if (window.enableAutoLoad) this.onRetrieveLocation_(a, b);
      }, 35000);
      b.hasComments?b.locationRetrieved(“/comment_service_ajax?action_get_comments=1&pbj=1”,void 0):b.locationRetrieved(“/related_ajax”,void 0);a.stopPropagation()
      }

      上記を実行した時点で下記のエラーを吐きます

      Uncaught SyntaxError: Function statements require a function name

      • HaniCheki より:

        それは、そのまま実行するのでなく書き換えるコードになります。

        こちらでも修正を試みました。
        しかし残念ながらこの記事の手法ではもうダメみたいです・・・。

    5. ゆい より:

      そうでしたか!残念ですが、あきらめます!
      ありがとうございました!

    タイトルとURLをコピーしました