YouTubeコメントを自動&スクロールなしで読めるスクリプトを作ってみる
- 2020-01-24
YouTubeでコメントを読む際、スマホならアプリを使えば動画を見ながらコメントをみることができますが、PCでブラウザからYouTubeをみているときはそれができません。
コメントをみるためにスクロールしたら動画も一緒にスクロールされるので見れなくなります。
コメントをスクロールなしで確認する方法はないのだろうか?
コメントをスクロールなしでみることができれば、動画をみながらコメントも確認できます。
なんかいい方法はないかと思って考えてたらひらめいたのでスクリプトを作ってみることにしました。
どんなものを作ったかはテキストだと説明が難しいので動画をご覧ください。
どうでしょうか?ちゃんと動画を画面内に含めたままコメントを読むことができています。
見た感じコメントを表示するだけのスクリプトにみえるかもしれませんが、そうではありません。
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側のスクリプトを書き換える時点でちょっと難易度高めだと思っています。
もしフルコードが欲しい方がいたらコメントくれたら渡せるかも・・・。