🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1819閲覧

Tampermonkeyでyoutubeのチャンネル名を取得する方法

Wakage-no-Italy

総合スコア1

Chrome

Google Chromeは携帯、テレビ、デスクトップなどの様々なプラットフォームで利用できるウェブブラウザです。Googleが開発したもので、Blink (レンダリングエンジン) とアプリケーションフレームワークを使用しています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/02/05 01:58

編集2021/02/05 06:33

前提・実現したいこと

youtubeで特定のチャンネルだけ見れるようにしたく、Tampermonkey(Javascript)でyoutubeのチャンネル名を取得し、それがホワイトリストのものと適合しなかったらウインドウを閉じる(見えなくする)というコードを動かそうとしています。
tampermonkeyのコードが転がっていたので流用したかったのですが、正しく動きません。

発生している問題・エラーメッセージ

下記のコードで、
var testString = $(".yt-user-info")[0].firstElementChild.innerHTML;
が機能せず、そこでコードが止まってしまいます(特にエラーなどなし)

該当のソースコード

JavaScript

1 2// ==UserScript== 3// @name Youtube Whitelist Script 4// @namespace http://tampermonkey.net/ 5// @version 0.1b 6// @description This script will remove the content from Youtube videos. Ignores whitelisted content 7// @author Louis Vaught 8// @match https://www.youtube.com/watch* 9// @copyright 2017, Louis Vaught 10// @require https://code.jquery.com/jquery-latest.js 11// ==/UserScript== 12 13var $ = window.jQuery; 14/////////////////////// 15// EDIT WHITELIST HERE: 16/////////////////////// 17 18var whitelist = [ 19 'TheBackyardScientist', 20 'Cody\'sLab', 21 'The Slo Mo Guys' 22]; 23//Make sure to match the name exactly. Not case-sensitive. 24 25////////////////////////// 26// String Search Function: 27////////////////////////// 28 29function searchStringInArray (str, strArray) { 30 for (var j=0; j<strArray.length; j++) { 31 var testStr = strArray[j].toLowerCase(); 32 var matchStr = str.toLowerCase(); 33 if (testStr.match(matchStr)) return j; 34 } 35 return -1; 36} 37 38//////////////////// 39// Main Script Body: 40//////////////////// 41 42$(document).ready(function() { 43 alert("main kokokara") 44 //Find the channel name on the page 45 var testString = $(".yt-user-info")[0].firstElementChild.innerHTML; 46// var testString ="hogehoge" 47 alert(testString) 48 //Search for the channel name in the array 49 var searchVal = searchStringInArray(testString,whitelist); 50 //If the channel isn't present, then delete content and error out: 51 if (searchVal==-1) { 52 $("#page-container").remove(); 53 alert("This channel isn't on the Youtube whitelist!"); 54 } 55});

試したこと

コードの上部で
// @require http://code.jquery.com/jquery-latest.js
var $ = window.jQuery;
と指定しているのでjQueryは使えると思うんですが、(エラーはでない)
実際には使えていないのかもしれません。

コードの間違い、もしくはjQueryの使い方の間違いなどがありましたらご指摘いただけますと嬉しいです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

miyabi_takatsuk

2021/02/05 02:21

まず、 JavaScriptは間にスペースを入れると、 Javaのことか?勘違いが起きるので、修正しましょう。 間にスペース入らないのが正式名称です。
eneko0513

2021/02/05 04:56

このページを開いたときにスクリプトが動いてほしい、というような参考になるURLがほしいです。 動画再生画面の話なのか、検索結果での話なのか等がわからないので。
Wakage-no-Italy

2021/02/05 05:52 編集

tampermonkeyでは下記のようにyoutubeの各動画ページでスクリプトが動くように指定しています。 // @match https://www.youtube.com/watch* 各動画ページでページ情報を確認し、チャンネル名を取得し、リストにあるかを判断したいです。 先ほどまでコードの一部分しか記載していなかったので、すべて記載しました。
guest

回答2

0

ベストアンサー

※質問文に貼られているコードタグの ` が一つ足らないと思うので追加しておいてください。後ろのtampermonkeyは不要です。

画面上の要素にyt-user-infoというクラスの要素がないためnullなんじゃないかなと思います。

下記赤枠の所を取得するなら現時点のエレメントでは下記のコードで取れるんじゃないかなと思います。
イメージ説明

こちらを試してもらえますか?

javascript

1var testString = JSON.parse(document.querySelector("#scriptTag").innerText).author;

実現したいことが再生画面上に来てからというのがマストの要件なら仕方ないと思うのですが、個人的には開く前からそもそもリストから消えていてほしいなと思ったりしました。

// ここから追記

まず前提としてjquery関連は使わないようにしたほうが良いので無しにしましょう。
外部ライブラリに依存すると仕様変更の追従が厄介になります。
何か動作確認してみましたが何か他のJqueryとバッティングしているのか正しく動作しませんでした。

自分の方でスクリプト組んでかんたんに動作確認したやつ貼ります。
nameとか諸々デフォルトにしているので修正してください。
ただ、要素のREMOVEをしても、動画自体が消えるわけではないので
恐らく主さんが想像しているようなこととはちょっと違う結果になると思います。
(プレイヤーは消えるが音声は再生されたまま)
あとはホワイトリストにかからない動画を見る→ホワイトリストの動画を見る(そうするとプレイヤー領域が消えたままで、リロードをすると直る)これはYoutubeのページが非同期で画面を生成するような仕組みのため起きます。

このようにいくつか課題がありますが、これをどうするかはちょっとご自身で考えて工夫してみてください、多分実現はできると思います。
例えばブラウザバックに変えるとか、別のアプローチもできるんじゃないかなと。

それで原因だった所ですが、そもそもスクリプトが走るタイミングが画面を開いたときだったので、名前の要素の部分がない状態で取得処理が走っていました。
コンソール上だと要素出てるから気づけなかったです。
なのでインターバルで名前の部分が出るまで待機してから削除処理をするようにしました。

javascript

1// ==UserScript== 2// @name New Userscript 3// @namespace http://tampermonkey.net/ 4// @version 0.1 5// @description try to take over the world! 6// @author You 7// @match https://www.youtube.com/watch?v=* 8// @grant none 9// ==/UserScript== 10 11(function() { 12 'use strict'; 13 14 /////////////////////// 15 // EDIT WHITELIST HERE: 16 /////////////////////// 17 18 var whitelist = [ 19 'TheBackyardScientist', 20 'Cody\'sLab', 21 'The Slo Mo Guys' 22 ]; 23 24 function searchStringInArray (str, strArray) { 25 for (var j=0; j<strArray.length; j++) { 26 var testStr = strArray[j].toLowerCase(); 27 var matchStr = str.toLowerCase(); 28 if (testStr.match(matchStr)) return j; 29 } 30 return -1; 31 } 32 33 var set_interval_id = setInterval(findTargetElement, 1000); 34 35 function findTargetElement() { 36 if(document.getElementById('scriptTag') != null) { 37 clearInterval(set_interval_id); 38 //alert('ページの読み込みが完了したよ!'); 39 // Your code here... 40 //alert("main kokokara") 41 //Find the channel name on the page 42 var testString = JSON.parse(document.querySelector("#scriptTag").innerText).author; 43 // var testString ="hogehoge" 44 //alert(testString) 45 //Search for the channel name in the array 46 var searchVal = searchStringInArray(testString,whitelist); 47 //If the channel isn't present, then delete content and error out: 48 if (searchVal==-1) { 49 document.querySelector("#player-theater-container").remove(); 50 //alert("This channel isn't on the Youtube whitelist!"); 51 } 52 } 53 } 54 55 56})();

投稿2021/02/05 06:26

編集2021/02/05 09:01
eneko0513

総合スコア349

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Wakage-no-Italy

2021/02/05 06:39 編集

回答ありがとうございます。上記のコードを入れて var testString =$("a.yt-simple-endpoint.style-scope.yt-formatted-string").innerHTML; alert("testSting="+testString) としてみたところ、 testSting=undefined と出力されてしまいました。。 必要のないチャンネルが初めから検索画面から消えてくれているほうが理想ですね。。。 youtube中毒の自分には何かしらのストッパーがあるだけ効果的なので、まずは簡単なところから始めてみます。
eneko0513

2021/02/05 06:45 編集

追記しました。 こちらを試してもらえますか?
Wakage-no-Italy

2021/02/05 06:51

ありがとうございます。 追記いただいた部分を試したのですが、今度は出力も表示されませんでした。代入部分でエラーが起き、終了したのかと思われます。 var testString = JSON.parse($("#scriptTag").innerText).author; alert("testSting="+testString)
eneko0513

2021/02/05 06:56

var $ = window.jQuery; この時$をconsole.logで出すと何が出ますか?
eneko0513

2021/02/05 06:57

回答追記しました。 jqueryが読み込まれていない可能性を考慮してquerySelectorを使う構文に変更してみました。
Wakage-no-Italy

2021/02/05 07:09

追記いただいたもので試すと、testStringにチャンネル名が入りました!ありがとうございます! alert($)で表示すると、function(e,t){return new k.fn.init(e,t)}とでました。 続けざまの質問で大変恐縮ですが、 これはjqueryが読めていないということでしょうか。 testStringの文字列がwhitelistの文字列にない場合 $("#page-container").remove(); という、(おそらく)ページを見えなくする動作も実施したいので、 jqueryを読めるようにする、もしくは読めていなくても使えるようにしたいです。
Wakage-no-Italy

2021/02/05 07:19 編集

#見るところを間違えていたため、下記コメントを修正しました。 console.log($); を試すと、consoleに ƒ (e,t){return new k.fn.init(e,t)} とでました。
eneko0513

2021/02/05 07:19

console.log(typeof $ === "function"); console.log(typeof jQuery === "function"); これの結果はどうですか?
Wakage-no-Italy

2021/02/05 07:26

重ね重ね初歩的な質問で恐縮ですが、consoleの結果を確認するには、ブラウザでF12を押して 右にでてくるconsole画面をみればよいでしょうか。 このような表示が出ています。 Content script running DevTools failed to load SourceMap: Could not load content for https://www.youtube.com/s/desktop/b9a7b031/jsbin/custom-elements-es5-adapter.vflset/fast-shim.js.sourcemap: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE DevTools failed to load SourceMap: Could not load content for https://www.youtube.com/s/desktop/b9a7b031/jsbin/web-animations-next-lite.min.vflset/web-animations-next-lite.min.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE DevTools failed to load SourceMap: Could not load content for https://www.youtube.com/s/desktop/b9a7b031/jsbin/webcomponents-all-noPatch.vflset/webcomponents-all-noPatch.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE userscript.html?name=Youtube%20Whitelist%20Script.user.js&id=267c5ae9-0118-4555-af3a-223534bb2816:22 true The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle. watch?app=desktop&v=UY5r3NzmLj8&pbjreload=101:1 The resource https://r6---sn-oguelne7.googlevideo.com/generate_204?conn2 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. watch?app=desktop&v=UY5r3NzmLj8&pbjreload=101:1 The resource https://i.ytimg.com/generate_204 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally. watch?app=desktop&v=UY5r3NzmLj8&pbjreload=101:1 The resource https://r6---sn-oguelne7.googlevideo.com/generate_204 was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate `as` value and it is preloaded intentionally.
eneko0513

2021/02/05 07:38

F12で見る場所はそのConsoleの所で良いです。 上にあるのは見た感じ関係なさそうなエラーのような? ご自身のスクリプトの alert("main kokokara"); の下あたりに console.log("$: "+ typeof $ === "function"); console.log("jquery: " + typeof jQuery === "function"); を差し込んでその結果をコンソールで見てください。
Wakage-no-Italy

2021/02/05 07:46

$(document).ready(function() { alert("main kokokara") console.log("$: "+ typeof $ === "function"); console.log("jquery: " + typeof jQuery === "function"); として、コンソールにでてきた赤文字だけ抽出すると Uncaught TypeError: Cannot read property 'innerText' of null at HTMLDocument.eval (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/userscript.html?name=Youtube%2520Whitelist%2520Script.user.js&id=267c5ae9-0118-4555-af3a-223534bb2816:57) at e (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/userscript.html?name=Youtube%2520Whitelist%2520Script.user.js&id=267c5ae9-0118-4555-af3a-223534bb2816:3) at Window.t (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/userscript.html?name=Youtube%2520Whitelist%2520Script.user.js&id=267c5ae9-0118-4555-af3a-223534bb2816:3) at <anonymous>:3:100 at E.z.<computed> (eval at exec_fn (watch:1), <anonymous>:43:442) The service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle. he service worker navigation preload request was cancelled before 'preloadResponse' settled. If you intend to use 'preloadResponse', use waitUntil() or respondWith() to wait for the promise to settle.
Wakage-no-Italy

2021/02/05 07:50

ちなみに、 alert("$: "+ typeof $ === "function"); alert("jquery: " + typeof jQuery === "function"); とすると、どちらも false とでました
eneko0513

2021/02/05 09:02 編集

原因わかったので追記しました。
Wakage-no-Italy

2021/02/05 10:43

ありがとうございます! - jqueryに頼らないほうがいいこと - 名前の要素の部分がない状態で取得処理が走っていたこと など、非常に参考になりました! スクリプトの最後 if (searchVal==-1) {の中で、 window.open('about:blank','_self').close() として、強制的にページを閉じることとしてみました。 youtubeの検索ページからビデオページを開くとなぜかスクリプトが起動せず、再読み込みをするとスクリプトが動くなど、疑問点/修正点はまだ見つけられますが、 当初やりたかったところが解決できてよかったです。 親身にご対応いただき誠にありがとうございました!!
eneko0513

2021/02/05 10:48

お役に立てたなら良かったです。 >> window.open('about:blank','_self').close() これにはセキュリティの制約などもあるのでそちらも別途調べてみてください。 >> youtubeの検索ページからビデオページを開くとなぜかスクリプトが起動せず、再読み込みをするとスクリプトが動く これはYoutubeが非同期で動的にページが生成されるタイプだからです。 見た目上リロードしているように見えるかもしれませんが、実際はリロード(画面の再読み込み)せずに画面が変わっているため、スクリプトが最初に読み込まれた後に再読み込みが走らないのです。 そのため、要素が表示されるのを待つ、というのもある意味動的にページが作られるから必要な対応になっています。
Wakage-no-Italy

2021/02/05 10:59

>> window.open('about:blank','_self').close()は今のところ私の環境では動いているようですが、調べてみます。 >>これはYoutubeが非同期で動的にページが生成されるタイプだからです。 すみません、追記で書いていただいていたのはこのことですね。 納得いたしました。 これは対処しないといけませんね。勉強してみます。
Wakage-no-Italy

2021/02/05 11:10 編集

原理を正確に理解できたわけではありませんが、 // @match https://www.youtube.com/watch?v=* を // @match https://www.youtube.com/* と初めからスクリプトを動作させることで、 動画ページにいったら消してくれるようになりました! と思いましたが、whitelistの動画から他の動画に飛ぶとだめですね。 #まさにご指摘いただいていた点ですね。 勉強します
Wakage-no-Italy

2021/02/05 12:35 編集

たびたびすみません。 clearInterval(set_interval_id);をコメントアウトしたら、 ずっと裏でスクリプトが動いて、別の動画を見たときにチャンネル名を取得することができました。 この、裏でずっとスクリプトが動いているというのがどんな悪さをするかはわかりませんが、ひとまずこれで使ってみようと思います。
eneko0513

2021/02/05 13:07

1秒ごとに要素の取得処理をし続けますね。 負荷的な所はまぁそこまで大きくは無いでしょうが・・。
Wakage-no-Italy

2021/02/05 13:11

ちょっとアホっぽいコードとは思いますが、、、 まぁ一日の内多くても1時間も見ないのでたぶん大丈夫かなと。。。
guest

0

備忘録まで

// ==UserScript== // @name New Userscript // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match https://www.youtube.com/* // @grant none // ==/UserScript== (function() { 'use strict'; /////////////////////// // EDIT WHITELIST HERE: /////////////////////// var whitelist = [ 'ShiryuGL', 'Marina Takewaki' 'Les Mills' ]; function searchStringInArray (str, strArray) { for (var j=0; j<strArray.length; j++) { var testStr = strArray[j].toLowerCase(); var matchStr = str.toLowerCase(); if (testStr.match(matchStr)) return j; } return -1; } var set_interval_id = setInterval(findTargetElement, 1000); function findTargetElement() { if(document.getElementById('scriptTag') != null) { //clearInterval(set_interval_id); //alert('ページの読み込みが完了したよ!'); // Your code here... //alert("main kokokara") //Find the channel name on the page var testString = JSON.parse(document.querySelector("#scriptTag").innerText).author; // var testString ="hogehoge" //alert(testString) //Search for the channel name in the array var searchVal = searchStringInArray(testString,whitelist); //If the channel isn't present, then delete content and error out: if (searchVal==-1) { document.querySelector("#player-theater-container").remove(); window.open('about:blank','_self').close() //alert("This channel isn't on the Youtube whitelist!"); } } } })();

投稿2021/02/05 12:35

編集2021/02/05 12:39
Wakage-no-Italy

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問