【備忘録】noteで自動スキを付けるブックマークレットの解説

IT・WEB

noteの記事一覧ページを開いた状態で実行すると、未スキの投稿に対して指定した件数分まとめて「スキ」を付けられるブックマークレットのメモです。コードの動作原理・使い方・注意点をまとめておきます。


📌 ブックマークレットとは

ブックマークレット(Bookmarklet)とは、ブラウザのブックマーク(お気に入り)に登録できる小さなJavaScriptプログラムのことです。URLの代わりに javascript: から始まるコードを登録し、クリックするだけでWebページ上でスクリプトを即実行できます。

  • インストール不要・拡張機能不要
  • ブラウザのブックマークバーに登録するだけ
  • ページを開いた状態でワンクリック実行

🔧 完全なコード

以下が今回のブックマークレットの全コードです。

javascript:(function(){
    var clickCount = prompt('何回スキを付けますか?');
    clickCount = parseInt(clickCount, 10);
    if (!isNaN(clickCount) && clickCount > 0) {
        /* 未スキのボタンを抽出(aria-pressed="false" かつ ハートアイコンを持つもの) */
        var targetButtons = Array.from(document.querySelectorAll('button[aria-label="スキ"]')).filter(function(btn) {
            var isNotPressed = btn.getAttribute('aria-pressed') === 'false';
            var hasHeart = btn.querySelector('.a-icon--heart');
            /* 以前の形式(is-activeクラスがないもの)も考慮 */
            var isLegacyNotActive = !btn.querySelector('.is-active');
            return isNotPressed && hasHeart && isLegacyNotActive;
        });
        var actualClickCount = Math.min(clickCount, targetButtons.length);
        if (targetButtons.length > 0) {
            for (var i = 0; i < actualClickCount; i++) {
                targetButtons[i].click();
            }
            console.log(actualClickCount + '個の「スキ」を付けました');
        } else {
            console.log('「スキ」を付けるアイコンが見つかりませんでした');
        }
    } else {
        console.log('無効な数値が入力されました');
    }
})();

🔍 コード解説:処理の流れ

① 即時実行関数(IIFE)でラップ

javascript:(function(){
    // 処理
})();

(function(){ ... })() は即時実行関数式(IIFE: Immediately Invoked Function Expression)と呼ばれる書き方です。ブックマークレットでは、グローバルスコープの汚染を防ぐためにこのパターンが定石です。javascript: プレフィックスをつけることでブラウザがJavaScriptとして認識します。

② prompt() でクリック回数を入力

var clickCount = prompt('何回スキを付けますか?');
clickCount = parseInt(clickCount, 10);

prompt() はブラウザ標準のダイアログを表示し、ユーザーの入力を文字列として受け取ります。parseInt(..., 10) で10進数の整数に変換します。isNaN()> 0 のチェックで、数値以外や0以下の無効な入力を弾きます。

③ 未スキのボタンを取得する

var targetButtons = Array.from(document.querySelectorAll('button[aria-label="スキ"]')).filter(function(btn) {
    var isNotPressed = btn.getAttribute('aria-pressed') === 'false';
    var hasHeart = btn.querySelector('.a-icon--heart');
    var isLegacyNotActive = !btn.querySelector('.is-active');
    return isNotPressed && hasHeart && isLegacyNotActive;
});

ここが処理の核心部分です。3つの条件を組み合わせて「まだスキしていないボタン」だけを絞り込んでいます。

変数 セレクタ / 条件 意味
isNotPressed aria-pressed="false" WAI-ARIAの属性でボタンが未押下状態であることを確認
hasHeart .a-icon--heartクラスを持つ子要素 スキ(ハート)アイコンを内包するボタンであることを確認
isLegacyNotActive .is-activeクラスがない 旧デザインのnoteでスキ済みを示すクラスがない場合も考慮

なぜ3条件が必要か? noteのHTML構造は過去にデザイン変更されており、現行版では aria-pressed 属性で状態管理されていますが、旧バージョンでは .is-active クラスで管理されていました。両方の判定を組み合わせることで、どちらの構造にも対応できるようにしています。

④ 指定件数だけクリックする

var actualClickCount = Math.min(clickCount, targetButtons.length);
if (targetButtons.length > 0) {
    for (var i = 0; i < actualClickCount; i++) {
        targetButtons[i].click();
    }
}

Math.min() によって、ユーザーが指定した数と実際にページ上にある未スキボタンの数のうち小さい方を採用します。これにより「100件指定したがページに10件しかない」といった場合でも安全に動作します。その後、for ループで各ボタンの .click() を呼び出し、スキを付けていきます。


📖 使い方

登録方法

  1. ブラウザのブックマークバーを表示する(Chrome: Ctrl+Shift+B / Mac: Cmd+Shift+B
  2. ブックマークバーを右クリック →「ページを追加」または「ブックマークを追加」を選択
  3. 名前に「noteスキ一括」などわかりやすい名前を入力
  4. URLの欄に上記コードをそのまま貼り付けて保存

実行方法

  1. noteのフォローしているユーザーの記事一覧ページや、タイムラインページを開く
  2. ページが十分に読み込まれたことを確認する
  3. ブックマークバーの「noteスキ一括」をクリック
  4. ダイアログに「何件スキを付けるか」の数字を入力してOKを押す
  5. 自動でスキが付けられる

⚠️ 注意点・制限事項

  • 表示中のページ内のみ動作:ブックマークレットはページのDOMに対して動作するため、スクロールして表示されていない(まだ読み込まれていない)記事にはスキが付きません。先に十分スクロールして記事を読み込ませてから実行するか、複数回に分けて実行してください。
  • noteのHTML構造変更に影響される:noteがサイトのデザインやHTML構造を変更した場合、セレクタが一致しなくなり動作しなくなる可能性があります。動作しない場合はブラウザの開発者ツールでボタンのクラス名・属性を確認して修正が必要です。
  • 利用規約の確認:自動操作はnoteの利用規約に触れる可能性があります。個人的な備忘録・学習目的での利用にとどめ、大量・連続的な使用はお控えください。
  • 同期的クリックの制限:現在の実装はクリックをループで同期的に実行しています。noteがクリックイベントを非同期で処理している場合、連続クリックが一部無視されることがあります。その場合は setTimeout を使ったディレイ付き実装への変更を検討してください。

🛠️ カスタマイズTips

クリック間にディレイを入れる(より安定した動作)

連続クリックが安定しない場合は、各クリックの間に少し間隔を入れるとよいです。

javascript:(function(){
    var clickCount = prompt('何回スキを付けますか?');
    clickCount = parseInt(clickCount, 10);
    if (!isNaN(clickCount) && clickCount > 0) {
        var targetButtons = Array.from(document.querySelectorAll('button[aria-label="スキ"]')).filter(function(btn) {
            return btn.getAttribute('aria-pressed') === 'false' &&
                   btn.querySelector('.a-icon--heart') &&
                   !btn.querySelector('.is-active');
        });
        var actualClickCount = Math.min(clickCount, targetButtons.length);
        var i = 0;
        var timer = setInterval(function() {
            if (i >= actualClickCount) {
                clearInterval(timer);
                console.log(actualClickCount + '個の「スキ」を付けました');
                return;
            }
            targetButtons[i].click();
            i++;
        }, 300); // 300ms間隔
    }
})();

📝 まとめ

このブックマークレットのポイントをまとめます。

  • IIFEでスコープを閉じてグローバル汚染を防止
  • aria-pressed + .a-icon--heart + .is-activeの不在、3条件で「未スキボタン」を確実に特定
  • Math.min() で「指定数」と「実在数」の小さい方を安全に採用
  • 旧デザインのnoteにも対応できるようレガシー判定を含む

noteのHTML構造が変わった際のデバッグ方法や、改良版のアイデアがあれば随時この記事に追記していく予定です。

コメント

タイトルとURLをコピーしました