見出し画像

Geminiと一緒にXの広告濾過装置作ったよ。



間違えてブラウザーのUserscriptの拡張を開いて、何か簡単なUserscript作れないかなと思ってGeminiにためしに以下の質問をなげてみました。

xの広告削除するuserscriptって書ける?

はい、作成可能です。

ちなみに私のプログラミングスキルは初歩的なhtmlとCSSぐらいでjavascriptは理解していないけど、ざっくりした知識がある程度のオッサンです。

UserScriptとは


簡単に特定のサイトにスクリプト書いて使い勝手をよくするハックで、ブラウザーにUserscriptを実行させる拡張をインストールしてその拡張上で動くスクリプトを実行させる手順です。

代表的な拡張はFirefoxのGreseMonkyで後発は〇〇Monkyって名前です。
今回はChromeのブラウザーで使うのでFirefoxも対応しているTampermonkeyを使いました。

AIとの会話の流れ

xの広告削除するuserscriptって書ける?

はい、作成可能です。
X(旧Twitter)の構造は頻繁に変更されるため、特定のクラス名を狙うよりも、プロモーション投稿に共通する「プロモーション」というテキストや、特定のデータ属性(data-testid="placementTracking" など)を監視して非表示にするアプローチが一般的です。
以下に、基本的な構成のUserScriptを記載します。

一回目のスクリプトが数秒で完成。
広告は消えたもののXのプレミアムの課金とかがうるさい。

xのプレミアム広告や課金要素も削除してほしい。

プレミアム(X Premium)への勧誘や「アップグレード」ボタンなどは、特定の aria-label や data-testid をターゲットにすることで非表示にできます。
これらを一括で処理するTampermonkey用スクリプトを更新しました。

消えてないねメニューのプレミアムと検索カラム下の「プレミアムにサブスクライブ」ってブロックが残ってる

Xの仕様変更により、一部の要素が標準的なセレクタでは検知しにくくなっている可能性があります。
メニューの「プレミアム」ボタンと、サイドバー(検索カラム下)の「プレミアムにサブスクライブ」ブロックをより強力に、かつ確実に特定して削除するコードに修正しました。
以下のコードを現在のスクリプトと差し替えてください。

成功

良かったです。無事に消えたようで何よりです。
Xは頻繁にUIをアップデートするため、もしまた「プレミアム」の文字や広告がひょっこり現れたら、それは要素の構造(IDやクラス名)が変わった合図です。その際はまたいつでも言ってください。
快適なタイムラインをお楽しみください!

さっきのuserscriptで更に軽くする工夫ある?

低スペック機での運用を想定し、「CPU負荷(監視回数)」と「メモリ消費(無駄な処理)」を最小限に抑えるための最適化案をいくつか紹介します。
特にChromebookのようなデバイスでは、ブラウザのプロセスがCPUを食い潰すと一気に動作がカクつくため、以下の工夫が有効です。

Waja&Gem X濾過装置と名付けた。

素晴らしいネーミングですね!**「濾過装置」**という言葉が、不純物(広告や勧誘)を取り除いて、純粋なタイムラインだけを抽出するというこのスクリプトの本質を完璧に表現しています。
日本語の「濾過装置」という響きに、開発者の名前を冠したこのタイトルは、まさに「俺のシステム」という感じがして格好いいです。
では、この名前を正式に反映させた、低スペック機(Chromebook等)向け最適化済みの最終構成案をまとめます。

あとnotoのAIと作ってみたに応募するので会話の概要もまとめて
#AIと始めてみた と勘違いしてるがこのまま進行。

noteの「#AIとやってみた」への応募、いいですね! 「Waja&Gem X濾過装置」の開発プロセスは、まさにAIを単なる道具ではなく、特定の目的(低スペック機での最適化)に向けた「共同開発パートナー」として活用した良い事例だと思います。
記事に使いやすいよう、今回の開発の歩みを概要としてまとめました。


【概要】AIと共同開発した超軽量X(Twitter)環境改善システム

1. 開発の背景と目的

  • 課題: Xのタイムラインに流れる広告(プロモーション)や、頻繁なPremium(課金)への勧誘が、本来のユーザー体験を阻害している。

  • 技術的制約: 高性能なM4 Mac miniから、リソースが限られたChromebookまで、複数のデバイスで共通して「低負荷・低メモリ消費」で動くシステムが必要。

  • 解決策: 既存の重い拡張機能に頼らず、必要最小限のコードで動くUserScriptをAI(Gemini)と共に自作する。

2. 共同開発プロセス(AIとの対話)

  • 初期フェーズ: Xの動的な構造(ランダムなクラス名など)を回避し、「テキスト判定」と「データ属性」を組み合わせた確実な広告検知ロジックを構築。

  • 改善フェーズ: 「消えない要素(プレミアム勧誘ボタン等)」に対し、URL(href)や特定のaria-labelを狙い撃ちする「外科手術的」なコードへアップデート。

  • 最適化フェーズ(重要): 低スペック機での動作を考慮し、CPUを酷使するリアルタイム監視(MutationObserver)から、一定間隔でスキャンする「定期濾過方式」へ転換。さらに一度処理した要素をスキップするフラグ管理を導入し、動作を極限まで軽量化。

3. 到達点:Waja&Gem X濾過装置

  • 名称の由来: AIと開発者の合作であることを示す「Waja&Gem」に、不純物を取り除き純粋な情報だけを抽出する「濾過装置」というコンセプトを融合。

  • 成果: 広告だけでなく、サイドバーの課金誘導やメニューの不要なボタンを完全に除去。メモリ消費を抑えつつ、OSを問わず軽快に動作する「俺のシステム」が完成。

4. 結論:AIと人間の役割分担

  • 人間(Waja)が「低スペック機での優位性」や「エコな設計」といった明確な戦略とシステム哲学を提示し、AI(Gemini)がそれを具体的なコードへ落とし込み、技術的な最適化案を提案する。この相互作用により、汎用品にはない「自分専用の最適解」を短時間で生み出すことができた。


noteの記事にする際、この構成をベースに「特に低スペック機でのメモリ管理の重要性」や「自分好みに環境を濾過する楽しさ」を肉付けすると、非常に面白い内容になると思います。応募、応援しています!

Waja&Gem X濾過装置。完成!

完成したコードがこちらです。

// ==UserScript==
// @name         Waja&Gem X濾過装置
// @namespace    https://note.com/999wj
// @version      1.4
// @description  Waja & Gemini 合作:低スペック機向けに負荷を最小限に抑えたX(旧Twitter)広告・課金要素の濾過システム
// @author       Waja & Gemini
// @match        https://x.com/*
// @match        https://twitter.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=x.com
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    const staticSelectors = [
        'a[href="/i/premium_sign_up"]',
        'a[aria-label="Verified Organizations"]',
        'a[aria-label="プレミアム"]'
    ];

    const filterX = () => {
        // 1. 静的ナビゲーション要素の濾過
        staticSelectors.forEach(s => {
            const el = document.querySelector(s);
            if (el) el.remove();
        });

        // 2. タイムラインのプロモーション投稿を濾過
        const articles = document.querySelectorAll('article[data-testid="tweet"]:not([data-filtered])');
        articles.forEach(article => {
            article.setAttribute('data-filtered', 'true'); // 処理済みマーク(負荷軽減)

            if (article.innerText.includes('プロモーション') || article.innerText.includes('Ad')) {
                const container = article.closest('div[data-testid="cellInnerDiv"]');
                if (container) container.remove();
            }
        });

        // 3. サイドバーの課金誘導ブロックを濾過
        const sidebars = document.querySelectorAll('aside[role="complementary"]:not([data-filtered])');
        sidebars.forEach(sidebar => {
            sidebar.setAttribute('data-filtered', 'true');
            if (sidebar.innerText.includes('プレミアムにサブスクライブ') ||
                sidebar.innerText.includes('Subscribe to Premium') ||
                sidebar.innerText.includes('認証済み組織')) {
                sidebar.remove();
            }
        });
    };

    // 低スペック機への配慮:0.5秒間隔の定期濾過(CPU負荷を抑制)
    setInterval(filterX, 500);

    filterX();
})();

あとがき

Xの広告削除に関してはControl Panel Twitterような拡張を使えば簡単にできるので、今回AIをどこまで上手く使えるかの練習のお題にXの広告削除を試したわけで実験は大成功でした。


いいなと思ったら応援しよう!