こんにちは、chrome歴3年のぴのです。
皆さんウェブサイトに表示される広告をどう思いますか?管理人は死ぬほど嫌いです。無料のブログサービスではなくレンタルサーバーでホームページを運営している理由の一つでもあります。
というわけで、今回は厄介な広告をブロックするchrome拡張を作ってみることにしました。googleストアを探せば広告ブロックするアドオンはありますが、まあせっかくなので勉強も兼ねて自作してみることにしました。
目標
本当は汎用的に使える広告ブロック拡張を作りたかったのですが、広告を出す側もさまざまな手を使って広告ブロックをすり抜けてきて、なかなか汎用的な広告ブロック拡張を作るのは大変そうです。
そこで今回は、「プリコネ攻略」に出現する広告を全てブロックすることを目標に広告ブロック拡張を作っていきたいと思います。
chrome拡張を作る
適当なフォルダを作る
ドキュメントフォルダの中に「AdBlock」というフォルダを作ります。以降のファイルは全てこの中に配置します。
manifest.jsonを作る
拡張機能の情報が書かれたJSONファイルを作ります。(説明のために//コメントを書いていますが、実際にはJSONはコメントが書けません)
{
"manifest_version": 2, //JSONのバージョン
"description" : "Delete Advertisement", //説明
"name": "AdBlock", //名前
"version": "0.1", //バージョン
"browser_action": { //拡張アイコンクリック時の動作
"default_popup": "popup.html" //ポップアップするHTMLファイル
},
"content_scripts": [{ //開いているページでの動作
"matches": ["http://*/*", "https://*/*"], //対象のURL *で全てのサイトが対象
"js": ["jquery-3.5.1.min.js", "adBlock.js"] //動かすスクリプト
}],
"permissions": [ //必要な権限
"tabs" //タブへのアクセス
]
}
popup.htmlを作る
拡張アイコンをクリックしたときにポップアップするHTMLファイルを作っていきます。main.jsを読み込ませることで動的な処理が可能になります。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Delete popup</title>
</head>
<body>
<h2>AdBlocked</h2>
<script src="main.js"></script>
</body>
</html>
main.jsを作る
popup.html読み込み時(≒拡張アイコンクリック時)に動作させるmain.jsを作ります。今開いているタブに対して空のメッセージを送り、タブでの処理を開始させます。
document.addEventListener("DOMContentLoaded", () => { //読み込み直後処理
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => { //今開いているタブ
chrome.tabs.sendMessage(tabs[0].id, {}, (res) => { //メッセージを送る
setTimeout( () => { window.close(); }, 700); //0.7秒後にpopup.htmlを閉じる
});
});
});
少しややこしいですが、sendMessageの第3引数はメッセージを送った先の処理後に実行される関数で、この関数が送られるわけではありません。
adBlock.jsを作る
実際に広告を削除するスクリプトを書いていきます。最近の広告は1回消したぐらいでは復活するので、広告削除関数はページ読み込み後自動的に4回発動するようにしました。それでも消せなかったときのために、手動で拡張アイコンをクリックして消せるようにしました。
広告削除関数本体は、埋め込みによく使われるiframeタグの削除をまず試してみましたが、(ブロック対策なのか)それを回避して生成される広告が結構あったのでページのHTMLを確認して広告に使われているクラスの要素を削除するようにしました。
※iframeタグは広告以外にもyoutube動画の埋め込みなどにも使われるため、今の書き方だとそれらも消えてしまうことに注意
$(document).ready(() => { //ページ読み込み直後
adBlock();
});
window.onload = () => { //ページ読み込み完了時
adBlock();
setTimeout(adBlock, 3000); //3秒後
setTimeout(adBlock, 5000); //5秒後
}
chrome.runtime.onMessage.addListener((msg) => { //main.jsからメッセージが送られてきた時
adBlock();
return true;
});
const adBlock = () => { //広告削除
Array.prototype.slice.call(document.getElementsByTagName("iframe")).forEach((el) => {
el.remove();
});
Array.prototype.slice.call(document.getElementsByClassName("yjAdImage")).forEach((el) => {
el.remove();
});
Array.prototype.slice.call(document.getElementsByClassName("yadsOverlay")).forEach((el) => {
el.remove();
});
}
なぜか(main.jsでも使用した)ページ読み込み直後に実行される関数が動作しなかったので、代わりにjQueryのready()関数を使いました。今考えたらどうせあと3回も実行するのだから要らなかった気もします。
jQueryをダウンロードする
jQueryとはJavaScriptで使える便利なライブラリです。「jQuery」の一番上のproductionと書かれているものをクリックして開き、右クリックで保存しましょう。他のファイル同様、「AdBlock」フォルダ内に配置します。ready関数を使わないなら不要です。
拡張機能に設定する
chromeブラウザの右上から「設定->拡張機能」を開き、右上の「デベロッパーモード」をオンにしてから、「パッケージ化されていない拡張機能を読み込む」をクリックします。エクスプローラーが開くので、「AdBlock」フォルダを選択したら設定完了です(以降はデベロッパーモードをオフにしても大丈夫です)。
動作を確認
広告消えた!!!!やったぜ!!!!!
おわりに
思っていたより結構簡単にchrome拡張が作れて楽しかったです。広告も消えて万々歳!
課題としてはもっと汎用的に使えるようにすることでしょうか。iframeをまるまる消してしまうと広告以外も消してしまうし、クラス指定だとキリがないです。広告の中には乱数みたいなidやクラスが付けられているものもありました。
今回は初めてのchrome拡張だったで、動作確認のつもりで作りました。次はもっとちゃんとした(?)ものを作ってみようかな。
コメント