概要
以前作成した記事の第2回になります
google chrome拡張機能を自作して、自分の作りたいものを作ろうという企画になります
目指しているものとしては「youtubeの動画再生時に広告を表示しなくするのではなく、広告は再生して良いのでスキップボタンを自動で押したい」というものになります
前回までの内容では、youtubeを開いた際に通知を画面上に表示するというところまでが完成しておりました
今回でどこまで行けるかわかりませんが、頑張りたいと思います
本題
繰り返しとある要素をクリックする機能を作ってみる
急に求めているものを作れるわけではないので、近しいことを実装していくようにします
まずは繰り返し指定した要素をクリックできないと話にならないのでその部分を実装してみます
繰り返し処理を実行するのは基本的にどの言語でもfor文だと思いますが、今回やりたいこととしては一定時間ごとに繰り返し処理を行いたいということになります
javascriptで実現するにはsetIntervalメソッドというものを使用します
使い方としては以下のように第一引数で繰り返し処理したい関数を指定し、第二引数で繰り返しの秒数を指定します(ミリ秒単位)
// setInterval(function, delay, [param1, param2, ...]);
//
setInterval(() => {
console.log("Hello");
}, 1000);
console.logの部分を特定の要素をクリックする処理に書き換えることで、一定時間ごとにその要素をクリックしてくれるようになるというわけです
ここまでの内容を用いて作成したjavascriptがこちらです
処理を関数に切り出して、ページ読み込み時に呼び出すようにしています
この実行内容の結果としては10s後から5s間隔でyoutube概要欄を折りたたむ、広げるということを繰り返してくれます
要素が消えるのではなく、要素に対してhiddenがついたり消えたりするというところがなかなか気づけずに時間がかかってしまいました
説明していないsetTimeoutメソッドを使用しています
これは指定した時間だけ待機するもので初めに数秒間待つことで要素が全て読み込まれるのを待っています
function clickButton() {
setTimeout(() => {
const targetElement = document.querySelector('#description-inner.style-scope.ytd-watch-metadata');
if (targetElement) {
setInterval(() => {
const nextElement = document.querySelector('#collapse.button.style-scope.ytd-text-inline-expander')
if (nextElement.hasAttribute('hidden')) {
const targetElement = document.querySelector('#description-inner.style-scope.ytd-watch-metadata');
targetElement.click();
} else {
nextElement.click();
}
}, 5000);
}
}, 10000);
}
window.addEventListener('load', () => {
clickButton();
});
クリックしたい要素の調べ方
コードの実装ではないですが、クリックしたい要素の調べ方を記載しておきます
詳しく知りたい部分について「右クリック→検証」で開発者ツールを開いて要素を読み理解をするということをする方法で探し出しています
もっと効率の良い調べ方があると思うのですが、泥臭くいくしかまだ知りません
良い手段ご存知の方は、教えていただきたいです
youtube動画のプレイヤーの要素をクリックすることはできるのか
開発者ツールや検証で調べていくうちにある疑問が出てきました
動画流れているプレイヤー部分はクリックできるのか?
Webページであるからにはイエスなのでしょうが、プレイヤー上では右クリックを単に右クリックするだけだと検証のボタンが出てこず(清書の段階で2回右クリックすれば検証ボタン出てきました)
ここではプレイヤー上の要素がクリックできるのかについて詳しく書きたいと思います
見た目で簡単に結果がわかる再生ボタンをクリックできるかを試しました
単純にプレイヤーの要素を深ぼっていき、再生ボタンを担当している要素を見つけ出すことでクリックすることが確認できました
以下は再生ボタン要素が存在すれば5s間隔で再生ボタンをクリックするという内容になります
今更ながらyoutubeは要素が多すぎるということとidがない、class名にスペースが存在するといったことがありますが、以下のように先頭にドット、スペースをドットに置き換えることで1つしか存在しない要素についてクリックすることができます
function clickButton() {
setTimeout(() => {
const targetElement = document.querySelector('.ytp-play-button.ytp-button');
if (targetElement) {
setInterval(() => {
targetElement.click();
}, 5000);
}
}, 10000);
}
// ページが読み込まれたときに通知を表示
window.addEventListener('load', () => {
clickButton();
});
最後の試練
ということでプレイヤー上の要素もクリックできることがわかったところで本題に挑戦します
ここまで細分化して原理がわかっていればやることは簡単で、広告スキップボタンの要素を探せば良いだけです
探し出したところytp-skip-ad-buttonというクラス、skip-button:2というidが広告スキップボタンを管理していそうでした
なので当然、const targetElement = document.querySelector('#skip-button\\:2');と書いてクリックしたのですが、なぜか実際には広告がスキップできず、、
他のプレイヤー上の要素(広告が流れている間の広告主の情報や実際にその商品を購入するというボタン要素はクリックすることができました)
なにが良くなかったのかいろいろ調べたのですが、あまりはっきりとせずに終わることとなってしまいました
ただ怪我の功名とも言えるのですが、これまで拡張機能の開発をVSCodeで行い実際にjavascriptを修正しては拡張機能を管理で再読み込みをしていました
ですが、開発者ツールのコンソールから実際にjavascriptを実行することができることを知り、調査の効率を上げることができました(これまではyoutube広告が表示されるまで動画を何度も再生したり、キャッシュクリアなどをしておりました)
終わりに
今回で作り終えることができず、なんとも歯がゆい結果に終わってしまいましたが引き続きこっそりと裏では調査を進めておきたいと思います
いずれ皆様の前にちゃんとした形で共有できるように頑張りたいと思います