アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

Greasemonkey で Google 検索結果をフィルタリング

最近 Google 検索を利用していると、ほとんど同じ内容をコピペした質問系サイトや英語サイトを強引に機械翻訳してまるで呪文のような状態になってるサイトがいくつもヒットして気になっていた。これらをまとめて消したり 2ch でいうところのあぼーん的な置換を実行する方法を検討したところ Firefox なら Greasemonkey を使うのがよさそうだった。

というわけで Greasemonkey による Google 検索結果のフィルタリングを試してみる。

Greasemonkey のインストール

Firefox Add-on として Greasemonkey をインストール。有効にするためには Firefox の再起動が必要となる。

Greasemonkey は指定されたサイト上で任意の JavaScript を実行してくれる。うまく書けばページの内容を自在に制御可能。今回の目的は Google の検索結果をいじることなので、まさにうってつけ。

スクリプトの追加

Greasemonkey がインストールされているならステータスバー (Firefox 4 の場合はアドオンバー) にかわいいおサルさんのアイコンがあるので、これを右クリックしてコンテキスト メニューを表示。その中から新規ユーザスクリプトを選ぶと以下のようなダイアログが表示される。

新規ユーザスクリプト

各項目の内容は以下。

項目 内容
名前 スクリプトの名前。ファイル名にも使用されるので半角英数を推奨。
名前空間 スクリプト間の変数・関数などの衝突を防ぐための文字列。スクリプトを配布する予定があるならそのサイトの URL にしておくとよい。
説明 スクリプトの説明。
実行するページ スクリプトを実行するページ。ワイルドカードも指定できる。例えば http::/www.google.* のように設定する。
実行しないページ スクリプトを実行しないページ。実行と同じように指定できる。特定ページを除外したい場合に設定する。

はじめて利用する時はスクリプトを編集するテキスト エディターも選択する。ファイル選択ダイアログが表示されるので好きなエディタの EXE を選ぶ。こだわりがなければメモ帳でもよい。

これらの設定が終わるとテキスト エディターでスクリプトが開かれる。初期状態では新規ユーザスクリプト ダイアログで入力した内容が、スクリプトの冒頭にコメントされている。以下のようになっているはず。

// ==UserScript==
// @name           Google search result filter
// @namespace      https://akabeko.me/
// @description    Google search result filter
// @include        http://www.google.*
// ==/UserScript==

これは設定も兼ねているので編集すれば実行するページなどを変更できる。

jQuery を利用する

このままスクリプトを書いてもよいのだがページ内の要素を選んだりするうえで jQuery を利用したいので、これを読み込むための処理を書く。

(function(doc, version, func) {
  var check = function() {
    if (typeof unsafeWindow.jQuery == "undefined") { return false; }

    func(unsafeWindow.jQuery);
    return true ;
  };

  if (check()) { return; }

  var script = d.createElement("script");
  script.type = "text/javascript";
  script.src  = "http://ajax.googleapis.com/ajax/libs/jquery/" + version + "/jquery.min.js";

  doc.getElementsByTagName("head")[0].appendChild(script);
  (function() {
    if (check()) { return; }
    setTimeout(arguments.callee, 100);
  } )();

})(document, "1.5.1", function($) {
    // ... ここに jQuery を利用する処理を記述 ...
} );

document 参照、jQuery バージョン、コールバック関数を引数に持つ匿名関数を定義。この中では Google CDN (コンテンツデリバリネットワーク) で公開されている jQuery 読み込みを <script> としてページに追加する。jQuery が定義済み、または CDN から読み込めたならコールバック関数へ jQuery の参照を渡すようになっている。

次に匿名関数を呼び出す。ポイントは第三引数。コールバック関数の引数に $ が指定されており、これが前述の jQuery への参照となる。コールバック関数内ではこれを使って jQuery を利用できる。

Google 検索結果のフィルタリング

スクリプトの準備が整ったので実際に Google 検索結果のフィルタリング処理を実装してみよう。

スクリプトが実行されるタイミングはページ読み込み時となり既に検索結果の DOM が形成されている。よってこの中から消したいものを選び CSS で非表示にする。処理としては以下のようになる。

(function(doc, version, func) {
    // ... 前述の jQuery を読み込む処理 ... 
})(document, "1.5.1", function($) {
  var hosts = [
    "example.com",
    "www.example.com"
  ];

  var filter = function(host, target) {
    var regx = new RegExp("^http:\/\/" + host.replace (".", "\.") + "\/", "i");
    return (target.attr("href").match(regx) != null);
  };

  for (var i = 0; i < hosts.length; ++i) {
    $("a.l")
      .filter(function() { return filter(hosts[i], $(this)); })
      .parents("li.g").css("display", "none");
  }
});

消す対象となるサイトのホスト名を hosts 配列に指定する。対象を細かく制御できるように正規表現もサポートする。はてなキーワードのようホスト名の先頭が複数のバリエーションを持つなら以下のように書く。

var hosts = [
  "(a|b|d|k|r|mgw).hatena.ne.jp"
];

filter 関数はこの条件で正規表現オブジェクトを生成して <a> タグの href と比較した結果を返す。正規表現が分かりにくければ消したいサイトのホスト名をそのまま並べてもよい。

以降の処理は Google の検索結果ページ HTML を Firebug などで見ると理解しやすい。l というクラスを持つ <a> タグを検索し、その href 属性を filter 関数で絞り込む。検出されたらその先祖となる要素を parents メソッドでたどり、その中の g クラスを持つ <li> タグを探して非表示にする。

css メソッドの部分を html メソッドに変更すれば任意 HTML への置換も可能。たとえばこの記事の冒頭に書いた 2ch 的なあぼーんを実現できる。

スクリプトの編集が完了したら保存して Firefox 上で Google 検索を実行。すると hosts に指定された条件に合致する内容がすべて消えるはず。Firebug を利用しているなら HTML パネルを表示すると消えた要素が淡色表示になったことを確認できる。