国税庁のリニューアルで調べ物ができなくて困ったのでChrome拡張機能作ってみた
という感じで Google Chrome の拡張機能を作ったんですが、その技術的背景についてはこちらに書きたいと思います。
プロダクト
ソースコード
Keywords
- Chrome Extension
- JavaScript
- 転置インデックス(inverted index)
- TF-IDF
開発背景
この拡張機能を作った背景は冒頭のリンクに書いたのですが、どういうものを作りたかったについての背景は書かなかったので、こちらに書きます。
実現したかったことは、まず、ユーザーは Google などの検索エンジンや、記事に貼られたリンクから、国税庁のホームページにアクセスします。すると、国税庁のサーバー側で renewal.htm にリダイレクトするのですが、そのリダイレクト直前のリクエストURL から新しい URL を類推して、そちらへのリンクを表示し、そこから新しいページに飛べるようにしたいと考えました。
実際にその方向で開発を進めていったのですが、度々拡張機能のアイコンをクリックして更にボタンを押下するのが面倒に感じ、結局 renewal.htm を検知したら自動的にブラウザ側でリダイレクト処理をかけるように仕様を変更しました。
しかしながら、僕は国税庁HPの開発者ではないので、リダイレクトルールを全て把握しているわけではありません。そのため、どうしてもリンク先を把握できない URL が存在してしまうと考えました。そこで、簡易的な検索機能(国税庁のサイト内検索は、過去のURLがインデックスされていてこちらも使い物にならない:2018年4月3日現在)も提供することで、リンク先がない場合の利便性もある程度確保しようとしました。
つまり、開発した機能は、
- renewal.htm を検知したら、直前のリクエストURLから新しいURLへリダイレクトする機能
- 手動でURLを入力し、リンク先を表示する機能
- 簡易的な全文検索機能
の3つです。
Chrome拡張機能の開発について
Chromeの拡張機能を作る上で参考にしたサイトは、ほとんど公式ドキュメントのみです。
https://developer.chrome.com/extensions
おそらく英語のページしか用意されていないと思うのですが、チュートリアルを読み進めていくと公式ドキュメントだけで開発できるように構成されています(そもそもドキュメントとはそうあるべきものだと思いますが)。
僕が余計なことを言うよりも、公式ページを読まれたほうが確実だと思いますので、こちらは割愛します。
リダイレクトのロジックについて
ITメディアのこちらの記事にもありますが、旧ページと新ページの URL の間には、一定のルールがあります。そこで、旧ページの URL を正規表現でマッチさせ、新ページの URL に置き換えることで、正しい URL にリダイレクトすることができるのではないか、というのがメインロジックになります。
実装は非常に単純で、ルールを入れても40行程度のコードです。
https://github.com/chase0213/ext-jptax/blob/master/redirector.js
全文検索機能について
前述の通り、全てのリダイレクトルールを知ることは僕にはできないため、検索機能を提供することにしました。その際、相手方のサーバーに負荷をかけると、最悪の場合訴訟されてしまう可能性があるため、ゆるーくHPをクロールしてインデックスを作成し、そのスコアを基に検索することにしました。
クロール部分については ruby で書いていますが、公開はしていません。
とりあえず Nokogiri と sleep(n) と sitemap.xml を使って情報を集めました。
その際、本文をクレンジング(タグの削除、ホワイトスペースや記号の削除)を行い、bigram を使って tokenize しています。その後、token毎に各文書での出現率とコーパス全体での出現率を記録しておき、そこから TF-IDF によってスコアを算出するということをしています(TF-IDF は log をとることが多いですが、スコアをファイルに保存してパッケージに同梱する関係で整数値をとって容量を削減するように調整しています)。
最後に、そこで計算されたスコアを jsファイルとして保存してパッケージ側から読み込んで、ブラウザ内で検索が完結するように実装しています。
ソースコードは突貫工事なのであまり綺麗ではないですが、この辺りです。
https://github.com/chase0213/ext-jptax/blob/master/popup.js#L102-L130
おわりに
技術的にはどれも大したことはないですが、この規模の拡張機能ならさくっと半日くらいで作れることがわかりました。
この拡張機能に関するバグや脆弱性、リダイレクトルールの追加は、基本的には github で募集中ですので、お気軽に contribute をお待ちしています。