Project 2

Osim Archive

Web Service

Web Service

Milestone

Wordpress • Twitter

Client

Personal

Role

UX Design / Front-end Development

Period

2021

WebsiteVisit →
Osim Archive

クソコメ☆ブロッカー

Issue

ヤフコメのクソコメを自動非表示しUX改善

Summary

Yahoo!Newsコメント欄の低品質コメントを自動非表示。読むに値しない、目にもしたくない、ノイズレベルのコメントを視界から消し去ります。

目に入ると読んでしまう。意図せず不快な気持ちにさせられる。そう感じてる感受性の強い方のために。 もう全部を読まなくていい。もう無駄に疲れない。 ユーザー大衆知で判断した、クリーンでマトモなコメントだけを表示し、あなたの心を守ります。

非表示基準を製作側の価値観やAIの判断ではなく、大衆知での判断ロジックを採用。 UIデザインは快適よりも少し違和感を残し有料版への足掛かり導線の1つに。サービス名は悪ノリ重視。ただし解り易いようchrome extensions内で名称が1行で入るように。

Short Story

悪ノリだけで付けたネーミングでしたが、パンチ力とフックが強いせいか、ローンチ後の初速が異常値をマーク。 一般的にローンチ後は一桁の数字で、ユーザー認知と共に放物線を描いていくものですが、KUSOKOMEは初速で50インストール。 が、数日後にスグに大量アンイストールされ一桁台へ。 おそらく「クソコメブロッカー」という解り易いサービス名から、あらゆるサービスのクソコメをブロックするサービスだと思われてインストールされたのかと。 「ユーザーは説明文を読まない」という定説が実証された動きでした。

とはいえ、それだけ需要がある事の証明でもあります。 無料枠でヤフコメをメインに対応し反応を伺い、有料版で他のサービス対応へ展開するという展望も用意してます。

ただChromeアドオンは開発者にとって“稼げる”ような場所ではなく、思いついたアイデアを片手間程度でカタチにする場所のように感じてます。自分のような大きくない開発母体ですと尚更。 ですのでやはり基本的には“自分が欲しいモノを作った”だけが開発思想の本当のところです。 自分以外にも同じように感じていて、少しでもその方々の役に立つ事が出来ていれば幸いです。

Yahoo!ニュースのコメント欄から、ノイズを減らす

治安の悪さで悪名高いヤフコメですが、個人的には嫌いではないコンテンツです。

“クソコメ以外は”

ヤフコメのようなユーザーコンテンツは、配信メディアやライター個人の主観を通す事なく、“リアルな民意”が表れている場所だと感じています。

記事によっては記事内容よりも先にヤフコメに眼を通すくらい自分の中での優先順位は低くないものとしてコンテンツを認識しています。

そこで厄介なのが、そのリアルさ故に混じり込んでる“質の低いコメント”。 気にしないつもりでいても目に入ってしまうものです。 そして少しずつ確かに消耗してる自分がいました。

Yahoo!ニュースのコメント欄には、攻撃的なコメント、炎上を狙ったコメント、内容の薄いコメント、的を得てない個人的価値観の一方的な発表など…ノイズが大量に溢れています。

一方で、コメント欄そのものをすべて非表示にしたいわけではない。 稀に穿った鋭いコメントも混ざり込んでいます。

リアルな民意や鋭いコメントは残したまま、質の低いコメントだけを除外できたらな。 そんな事を考えて開発の構想を練っていました。

そこで着目したのが、コミュニティによる評価を利用して、一定の基準を満たさないコメントだけを自動的に折りたたむという方法。

これは自分が眼を通す流れの習慣から気付いた発想でした。 コメント内容よりも、まず“共感した”や“なるほど”等の“評価が良い”コメントを選別して眼を通していました。 これだけでもだいぶ小さなライフハックではあったのですが、ならこの数字を取得して表示/非表示を最初からコントロールしてしまえばいいのではないかと。

全部読む必要なんて無いし、出来るなら目にも入れたくないですよね。 時間も人生も有限ですし、下らない事に意図せず消耗させられてるのは勿体ない。

当初はそんな単純な違和感から、このChrome拡張機能の開発を始めました。 振り返ってみれば、AI開発のムーヴメントが起き始めてた時期で「割と簡単に出来るでしょ」くらいの認識で始めたのですが、見積もりが甘く“ハマり”ました。


Overview

Project Overview

クソコメ☆ブロッカーは、Yahoo!ニュースのコメント欄を対象としたChrome拡張機能。

コメントに付けられた「共感した」「なるほど」「うーん」の評価数を読み取り、あらかじめ設定した条件に該当するコメントを自動的に非表示にする。

完全にコメントを消してしまうのではなく、必要であれば展開して確認できるようにすることで、フィルタリングと閲覧性のバランスを取っています。

初期要件

- Chrome Extensionとして動作
- Yahoo!ニュースに対応
- ページ表示後に自動実行
- コメントの評価数を利用して判定
- DOM操作を中心とした軽量な実装
- 非表示コメントは必要に応じて展開可能

非表示条件

以下のいずれかに該当するコメントを非表示とした。

1. 「共感した」「なるほど」「うーん」の総投票数が10件未満
2. 「うーん」が「共感した」+「なるほど」を上回る
3. 「うーん」が全投票数の50%以上
4. 評価が0票のコメント

非表示にしたことが分かるよう、小さな表示を残し、トグル操作によってコメント本文を再表示できるUIとした。


Development Timeline

Phase 01 — Idea & Planning

最初に着目したのは、Yahoo!ニュースのコメント欄にある「ノイズ」の多さ。

コメント欄を丸ごと消すのではなく、ユーザー自身が読む価値があると感じるコメントを残しながら、評価の低いコメントだけを視界から外す。

そのために、個別のコメント内容をAIなどで解析するのではなく、すでにYahoo!ニュース上で公開されているコミュニティ評価を利用することにした。

これなら判定処理を比較的シンプルに保ちながら、コメントの品質をある程度機械的にフィルタリングできる。


Phase 02 — DOM Scraping

最初の実装では、Chrome ExtensionのContent ScriptからYahoo!ニュースのDOMを解析。

取得対象は以下の情報。

- コメント本文
- 「共感した」
- 「なるほど」
- 「うーん」

コメントの評価数を取得し、判定ロジックに渡して非表示対象かどうかを判断する構成を作った。

しかし、ここから想定以上にYahoo!側のDOM構造に振り回されることになる…


🔥Problem 01 - 変動するclass名

Yahoo!ニュースはReactベースで構築されており、DOMには “sc-169yn8p-3” のような変動するclass名が使用されていた。

このようなclass名を直接セレクタとして利用すると、Yahoo!側のデザイン変更によって簡単に機能しなくなる。

最初は変動classに直接依存したが、安定性に問題があった。

そこで、コメントを識別するために「共感した」「なるほど」「うーん」といった投票ボタンのテキストを利用する方法も試した。

ただし、ページ全体を対象にテキスト検索すると、記事本文など別の要素まで誤って検出してしまう。

最終的には、コメントの構造を絞り込みながら、投票ボタンの存在を確認する方式へ進めた。

完全に変動classへの依存を排除することはできず、ここは最後まで技術的な制約として残った。


🔥Problem 02 - 記事本文まで消えてしまう

次に発生したのが、コメントだけを消したいのに記事本文まで非表示になってしまう問題。

Yahoo!ニュースのDOMには、記事本文とコメントで article 要素が複数存在し、単純に article を取得すると対象範囲が広すぎた。

さらに、コメント側には li > article > article という入れ子構造が存在していた。

そこで、単純なタグ検索ではなく、コメント内部に存在する投票ボタンのコンテナまで確認して対象を絞り込んだ。

この経験から、動的なWebサービスを対象とするDOMスクレイピングでは、単純なタグやclassだけではなく、その要素が本当に目的のデータを持っているかという構造的な条件まで含めて判定することが重要だと分かった。


🔥Problem 03 - 動的に追加されるコメント

Yahoo!ニュースのコメント欄は、ページを開いた瞬間にすべてのコメントがDOMへ存在するわけではない。

スクロールによってコメントが追加されるため、初回読み込み時に一度だけDOMを解析する方式では、新しく表示されたコメントを処理できない。

そこで MutationObserver を導入した。

DOMの変更を監視し、コメントが追加されたタイミングで再度検出処理を実行する。

さらに、MutationObserverだけでは取りこぼすケースへの対策として、一定間隔での定期スキャンも併用した。

これによって、Yahoo!ニュースの動的なコメント表示にも対応できるようになった。


Phase 03 - 判定ロジックの改善

基本的なフィルタリングが動くようになった後も、実際のYahoo!ニュース上でテストすると細かな問題が見つかった。

🔥Problem 04 - 「1.8万」のような表記

評価数には通常の整数だけでなく、「1.8万」のような日本語特有の表記が存在する。

単純に parseInt() を使うと、

"1.8万" → 1

となってしまう。

これは「1.8万票を獲得している評価の高いコメント」が、1票しかないコメントとして扱われる重大な判定ミスにつながる。

そこで数値抽出処理を専用化し、「万」が含まれている場合は10,000倍する処理を実装した。

function parseVoteNumber(text) {
  const match = text.match(/([\d,.]+)/);

  let num = parseFloat(match[1].replace(/,/g, ""));

  if (text.includes("万")) {
    num *= 10000;
  }

  return Math.floor(num);
}

これにより、

1.8万 → 18000
308   → 308

として扱えるようになった。


🔥Problem 05 - 0票コメント

もうひとつ意外な落とし穴になったのが、評価数が0のコメントだった。

当初は、

「0票 = まだ評価データが取得できていない」

と判断して処理をスキップしていた。

しかし実際には、

「誰からもまだ評価されていないコメント」

という意味である可能性があり、今回の仕様では非表示対象とすることにした。

if (totalVotes === 0) {
  return true;
}

ここでは、単純に0を null として扱ってしまうと判定処理まで到達しないという別の問題も発生。

そのため、

  • 投票ボタンが存在しない
  • 投票ボタンは存在するが票数が0

という2つの状態を分離して扱う必要があった。

小さな仕様変更だったが、実装上はデータ取得と判定ロジックの責務を見直すきっかけになった。


Phase 04 - v1.0 Release

最終的に、v1.0では以下の機能を実装。

Done

- ✅️ 親コメントの自動非表示
- ✅️ 3種類の評価基準による判定
- ✅️ 0票コメントの非表示
- ✅️ 「万」単位の評価数への対応
- ✅️ 非表示 / 表示のトグル
- ✅️ 「閉じる」ボタン
- ✅️ MutationObserverによる動的コメントへの対応

Technology

- Manifest V3
- Vanilla JavaScript / ES6+
- HTML5
- CSS3
- Chrome Extension API
- MutationObserver API
- Chrome Storage API
- Chrome Action API
- DOM API
- Chrome DevTools

子コメント(返信欄)への対応や、変動classへの依存を完全に排除することは、v1.0では後回しにした。


Phase 05 - Chrome Web Store

拡張機能として完成した後、Chrome Web Storeへの公開を進めた。

ここで、開発中には想定していなかった別の問題に直面した。

Chrome Web Storeでは、トレーダー(商用)アカウントとして登録すると、開発者情報として本名・住所・電話番号などの個人情報が公開される仕様だった。

当初はマネタイズも視野に入れていたためトレーダーとして登録していたが、個人情報を公開することとのトレードオフが大きかった。

そこで、

  1. ページを限定公開へ変更
  2. 非トレーダーアカウントへ変更
  3. 公開情報を見直す

という対応を行った。

法人化やバーチャルオフィスの利用も選択肢として検討したが、コストとの兼ね合いから採用せず、個人情報の保護を優先した。


Phase 06 - マネタイズ

公開後は、単に作って終わりではなく、実際にマネタイズできるかも検証した。

当初はChrome Extensionそのものに課金機能を持たせる方向も検討したが、Chrome Web Storeのアカウント要件との兼ね合いから、外部サービスを利用した投げ銭方式へ切り替えた。

利用したサービスは、

  • Ko-fi
  • Pixiv FANBOX
  • Stripe
  • PayPal

など。

popup.htmlにはサポートへの導線を追加。

UIについては、強く寄付を求めるのではなく、

このツールが役に立ちましたか?

という程度の控えめな誘導とした。

これは、プロダクトの価値を押し付けるのではなく、実際に役に立ったユーザーが任意でサポートできる形を意識したものだった。


公開後

リリースから数週間後、少ないサンプルながらユーザー動向を確認。

インストール数: 10
アンインストール数: 3
アクティブユーザー: 2

ページ閲覧数: 52
インプレッション: 21
コンバージョン率: 19.2%

地域:
日本: 50%
アメリカ: 50%

初期のコンバージョンは高かった一方で、継続率は20%にとどまった。

この数字を見て、単純に「コンバージョン率が高い = プロダクトが成功している」とは判断できないことも分かった。


何がうまくいかなかったのか

継続率の低さについては、ひとつの仮説としてネーミングの問題を考えた。

「クソコメ☆ブロッカー」という名前はキャッチーである一方、名前だけを見るとYahoo!ニュース専用のツールであることが伝わりにくい。

説明文にはYahoo!ニュース専用であることを記載していたが、実際には説明文を細かく読まずにインストールするユーザーもいる。

そのため、タイトルに「ヤフコメ」を含める案も検討した。

ただし将来的なYouTubeコメント欄などへの展開を考えると、特定サービス名をタイトルに固定することにもデメリットがある。

最終的にはタイトル変更を保留し、説明文の冒頭とスクリーンショットで「Yahoo!専用」であることを明確に伝える方向を選択した。

サンプル数自体が少なかったため、継続率についてはそのまま静観することにした。


学んだこと

Technical

動的DOMは、通常のDOM操作とは異なる問題。

静的なHTMLを対象にするDOM操作と、React・Lazy Load・仮想DOM・非同期描画が組み合わさった実サービスを対象にするDOM操作では、難易度が大きく違う。

今回の開発では、MutationObserverを使った動的DOMへの対応や、DOM構造を観察しながら対象要素を絞り込む方法を経験した。

Chrome拡張機能は、Vanilla JavaScript tだけで構築できる。

フレームワークを使わず、Vanilla JavaScriptを中心にChrome拡張機能を構築できた。

特にContent Script、Chrome Storage、Chrome Action、MutationObserverなど、ブラウザが提供するAPIを組み合わせることで、比較的軽量な構成でも実用的な拡張機能を作れることを確認できた。

データ抽出とビジネスロジックは分離すべき。

0票問題を通して、データが存在しないことと、データの値が0であることは別の状態だと分かった。

スクレイピングでは「取得できなかった」と「取得した結果が0だった」を同じ値で表現すると、後段の判定ロジックで意図しない挙動が起きる。

小さな拡張機能でも、データ取得と判定処理を分離して考える重要性を学んだ。


Design / Product

完璧な実装が、必ずしも適切な目標とは限らない。

開発当初は、Yahoo!ニュースのDOM変更にも完全に耐えられる構成や、子コメントまで含めた完全なフィルタリングを目指していた。

しかし、内部APIの利用はCORSや内部IDなどの制約があり、Yahoo!側の仕様に強く依存する。

そこで、実現可能性を優先して、

  • 子コメント取得をやめる
  • DOMスクレイピングに絞る
  • 評価数だけで判定する
  • 軽量な構成でリリースする

という方向へ仕様を変更した。

すべてを完璧にするよりも、まず動くものをリリースし、実際の反応を見ながら改善する。

このプロジェクトは、その判断を実践する最初の機会になった。

コンバージョン率が高いからといって、完成された製品であるとは限らない。

初期のコンバージョン率は高かったが、継続率は低かった。

この結果から、ひとつの指標だけを見てプロダクトの良し悪しを判断することの危険性も学んだ。


Future

今後の構想として、以下を検討していた。

v1.1

  • 子コメント(返信欄)への対応

v3.0

  • 判定基準を変更できる設定画面
  • ブロックレベルの段階設定(Level 1〜5)
  • ワードブロック機能

v4.0

  • YouTubeコメント欄など、他サービスへの対応
  • 有料版の実現

ただし、有料版についてはChrome Web Storeのアカウント要件や個人情報公開の問題があり、実現には追加の検討が必要な状態となった。


Project Flow

Planning
    ↓
Requirement Definition
    ↓
AI-Assisted Development
    ↓
DOM Scraping
    ↓
Technical Investigation
    ↓
Requirement Revision
    ↓
Chrome Extension / Manifest V3
    ↓
Chrome Web Store
    ↓
Monetization Experiment
    ↓
Analytics
    ↓
Iteration

このプロジェクトでは、単純に「Chrome拡張を作った」というだけではなく、

企画 → 実装 → 技術的な壁 → 仕様変更 → リリース → マネタイズ → 分析

という一連のプロダクト開発サイクルを実際に経験した。

それが、このプロジェクトで得た最大の成果だった。

そして何より、開発したサービスを自分自身が利用して愛用している事。 少なからずとも使ってくれているユーザーがいたという事。 これらが自分にとって意味のある事でもあったように思います。

Timeline

2026

Concept

見積り作成業務の効率化を構想

2026

Development

React + TypeScriptで開発

2026

Launch

Webアプリとして公開