錯誤試行

PCや生活の試行錯誤の成果を報告するブログ

ブラウザ閲覧履歴内全文検索方法についての調査

(2022/10/11)「Firefoxの閲覧履歴からキャッシュを取得・HyperEstraierのデータベースを更新する」を追記
(2020/5/8)「SSL通信の設定について」にSSL通信のキャッシュ・データベース登録について追記

ふとしたときに、ネットのどこかで読んだ文章を読み返したいが、一体どこで読んだのかどうしても思い出せず、閲覧履歴をしらみつぶしに当たっても全く見つけられずに歯痒い思いをすることがある。これを何とかしたいと常々思ってきたため、その解決方法を調べてみた。環境はUbuntu16.04 LTS。


結論

wwwoffleとHyper Estraierで実現できた。以下は解決方法を検討したところから。

ブラウザの拡張機能などでの対応

Chromeでは履歴内を全文検索する拡張機能が存在するが、Firefoxのアドオンは使い勝手が良くない。また複数のブラウザを使い分けていると、ブラウザ別に検索しなければならなくなるのがやや面倒。

  • Firefox
    CacheViewerというアドオンで閲覧キャッシュの全文検索が可能だが、ブラウザのキャッシュサイズを最大(1024MB)に設定していると途方もなく動作が重くなり、実用上支障が大きい。他に同じようなアドオンとしてCacheSearchや、閲覧したページを全てローカルに保存するSloggerといったアドオンがあったようだが、現行のFirefoxでは使えなかったり公開停止となっている模様。
  • Chrome
    Falconという拡張機能で実現されているらしい。ただし調べ物は主にFirefoxで行うことが多いため使い勝手については検証していない。
  • 風博士
    ブラウザそのものに履歴内全文検索の機能が付いているらしい。ただし以下同文。
  • Opera
    Operaもブラウザ自体に全文検索機能が付いていた模様。寡聞にして知らなかった。しかも2008年からであるらしい()。ただし以下同じ。

キャッシュサーバの調査

  • polipo
    簡単に導入でき、ウェブ閲覧を高速化できることで有名になったローカルキャッシュサーバ。キャッシュファイルが平文ではないため、全文検索は不可能。
  • squid
    企業などでも使われるという、polipoより大規模なキャッシュサーバ。キャッシュファイルが平文ではないため、全文検索は不可能。ウェブ検索結果ではnamazuとの組み合わせに触れているページがあるので、昔の古いバージョンは平文だったのかもしれない。
  • wwwoffle
    キャッシュファイルが平文。これが使える。ただしubuntuではパッケージ化されていないため、ソースからコンパイルする必要がある。インストール方法は参照サイトを参照。

検索エンジン

  • Fess
    全文検索サーバ。公式サイトで「5分で簡単に構築可能な全文検索サーバー」と説明されている通り簡単にできそう。Elasticsearchを検索エンジンとして利用しており、Elasticsearchは完全ヒットでなくても検索結果を拾ってくれる利点があるとのこと()。
    使ってみたところ、設定が悪いせいか検索結果から元URLにダイレクトに飛べなかったため、惜しくも選外とした。→(追記)「パスマッピング」で可能かもしれないが試していない。
  • Hyper Estraier
    全文検索システム。wwwoffleのキャッシュファイルを処理することで検索結果から元URLにダイレクトに飛ぶことができる! これが良さそう。設定方法は公式サイトに掲載されている。参照サイトを参照。また、wwwoffleにはHyper Estraierが同梱されているので、別途用意しなくていい
    →(訂正)Hyper Estraierの検索用のウェブページとスクリプトが同梱されているだけで、データベース作成用の実行ファイルは入っておらず、hyperestraierそのものは別途インストールが必要だったので訂正しておく。Ubuntuは標準リポジトリにパッケージが用意されているので、apt-get install hyperestraierでインストールできた。
  • Namazu
    全文検索システム。かなり昔にNamazuを使ったローカルwiki全文検索+検索結果からの元URLジャンプを設定した記憶があるが、検索性能的にHyper Estraierに優位性があるようなので()今回は使用しない。

SSL通信の設定について

SSL通信をキャッシュする

昨今はサイト全体でhttpsでの通信を行なうサイトが一般的となっているが、デフォルトではhttpしかキャッシュできず有用性が低いため、httpsで通信するページでもキャッシュできるように変更する。

コンパイルオプション・設定ファイルの変更

https通信のキャッシュに対応するには、wwwoffleをコンパイルする際に--with-gnutlsオプションを付けておく必要がある。

./configure --with-gnutls

設定ファイル(wwwoffle.conf)は、「SSLOptions」で以下の項目を追記する。

SSLOptions
{
enable-caching = yes
allow-cache = *:443
}
ブラウザの設定

(2022/10/11追記)

後述する通り、Firefoxのプロキシにwwwoffleを設定することができなくなり、この項目は実施する必要がなくなったため読み飛ばしてほしい。以下は記録として残しておく。

そして、「(wwwoffleキャッシュディレクトリ)/certificates/root/root-key.pem」のファイルが既に存在している場合、パーミッションが777になっているとうまく行かないので一旦ファイルを削除して、wwwoffleを再起動して同ファイルを再度作成させておく。
次に、「http://(サーバ):(wwwoffleポート番号)/certificates/root」のURLをブラウザで開き、[Download Certificate]から証明書をブラウザにインストールする。
「証明書の信頼性を設定してください」のダイアログで「ウェブサイトの識別に使用する」にチェックを入れると、httpsページもキャッシュすることができるようになる。

注意する点として、オンラインバンクのような機微情報を扱うサイトについては、通信内容をキャッシュしないよう「disallow-cache =」にオンラインバンクのサイトを登録する必要がある。
手元の環境では、設定が悪いのかもしれないが、Amazonや日経など一部のページでスタイルシートを読み込まなかったり、twitterなどでページが全く表示されなかったりといった不具合があった。そうしたサイトはブラウザ設定の「プロキシなしで接続」リストに記述して、wwwoffleを介さずにアクセスするようにした。

SSL通信のキャッシュをHyper Estraierデータベースに登録する

Hyper Estraierのestwolefindコマンド(/usr/bin/estwolefind)がデータベース作成の対象とするディレクトリは、estwolefindコマンドの中でwwwoffleキャッシュディレクトリ(/var/spool/wwwoffle)の下にあるhttpディレクトリが指定されていて、httpsでアクセスしたページはHyper Estraierのインデックス対象とならない。

そこで、estwolefindコマンドをコピーしてestwolefind-httpsのように別の名前を付け、ファイルの中身の'http'を'https'で全置換した上で実行すれば、httpsでアクセスしたページもHyper Estraierのインデックスに追加することができる。

Firefoxの閲覧履歴からキャッシュを取得・HyperEstraierのデータベースを更新する

(2022/10/11追記・2022/10/13 スクリプトを修正(「2. wwwoffleへ昨日の閲覧履歴を取り込む」の箇所))

上で書いた通り「証明書問題の発生」の不具合が発生したため、セキュリティ期限切れのFirefoxを使い続けるのも良くないので、重い腰を上げて対応することにした。

wwwoffleはブラウザのプロキシに設定する以外にも、端末からコマンドを実行することでウェブページのキャッシュを取得できる。ブラウザの閲覧履歴を取得して、そのURLをwwwoffleコマンドに指定してページを読み込ませてやれば、ブラウザのプロキシにwwwoffleを指定する必要がなく、証明書問題を回避することができる。

wwwoffleを使う目的は、ブラウザの閲覧履歴に登録されたページを全文検索(するためにキャッシュを取得)することであってオフラインモードの利用ではないので、プロキシに設定できなくても問題はない。

以下のスクリプトを/etc/cron.dailyに置いておけば(パーミッションを755にするのを忘れずに)、一日に一回、昨日の閲覧履歴がwwwoffleにキャッシュされ、hyperestraierのインデックスに登録されるようになる。
スクリプト3行目cpコマンドの「user-name-here」の箇所はユーザー名に、「profile-name-here」は、Firefoxで使用しているプロファイル名に置き換えること。

#!/bin/bash
## 1. Firefoxのデータベースから閲覧履歴をファイルに書き出し
cp /home/user-name-here/.mozilla/firefox/profile-name-here/places.sqlite /tmp
sqlite3 /tmp/places.sqlite "SELECT datetime(a.visit_date/1000000,'unixepoch','+9 hours') AS visit_date, b.url FROM moz_historyvisits AS a JOIN moz_places AS b ON a.place_id=b.id WHERE 1 ORDER BY a.visit_date ASC" > /tmp/sqlite3-firefox-history.txt
sqlite3 /tmp/places.sqlite '.exit'
rm /tmp/places.sqlite

## 2. wwwoffleへ昨日の閲覧履歴を取り込む
# 昨日の日付を取得
yesterday=`date --date '1 day ago' "+%Y-%m-%d"`

# grepで昨日の履歴を抽出し、wwwoffleで取り込めるようURLだけにして、localhostやローカルファイルの履歴は削除してファイルに出力
grep "$yesterday.*" /tmp/sqlite3-firefox-history.txt | sed -e "s/$yesterday.*|//g" | sed -e '/.*localhost.*/D' | sed -e '/^file:*/D' > /tmp/sqlite3-firefox-history-${yesterday}.txt

# wwwoffleに昨日の履歴を取り込む
while read LINE
do
    wwwoffle -d 0 $LINE
done < /tmp/sqlite3-firefox-history-${yesterday}.txt

# 一時ファイルを削除
rm /tmp/sqlite3-firefox-history-${yesterday}.txt
rm /tmp/sqlite3-firefox-history.txt

## 3. hyperestraierのインデックスを更新
# データベースをコピー
cp -aRpv /var/spool/wwwoffle/search/hyperestraier/db /var/spool/wwwoffle/search/hyperestraier/db-tmp
# コピーしたデータベースのインデックスを更新
estwolefind /var/spool/wwwoffle | estcmd gather -cl -fm -il ja -bc -px @uri -px _lfile -sd -cm /var/spool/wwwoffle/search/hyperestraier/db-tmp -
# コピー元のデータベースを削除
rm -rf /var/spool/wwwoffle/search/hyperestraier/db
# コピーしたデータベースを、元のデータベースのディレクトリ名に変更
mv /var/spool/wwwoffle/search/hyperestraier/db-tmp /var/spool/wwwoffle/search/hyperestraier/db

本来はデータベースから閲覧履歴を出力する段階で、昨日の日付に絞って出力した方がよいのだろうが、sqlite3の使用法を調べるのが面倒だったので、出力したファイルの方から昨日の履歴を取り出すことにした。
「wwwoffleに昨日の履歴を取り込む」の箇所は、URLリンクを記述したhtmlファイルを出力して以下のようにしても履歴を取り込むことができるのだが、コアダンプを出力して処理が停止しまうことがあったため、一行ずつ読み込むことにした。

wwwoffle -d 0 /tmp/sqlite3-firefox-history-${yesterday}.html

問題なく動作しているのが確認でき、晴れて最新版のFirefoxを使うことができるようになった。
運用開始から6年が過ぎ、閲覧キャッシュは50Gを超え(画像等は設定で除外している)、インデックスの更新に半日がかかるようになってしまった。

wwwoffleをプロキシに指定することができていた古いバージョンのFirefox ESR版(firefox-esr(91.11.0esr))は更新しないままにしておき、wwwoffleのオフラインモード(「wwwoffle -off」)を使って、消えてしまったウェブサイトを(wwwoffleのキャッシュに残っている場合に)閲覧する用途として使うことにしたい。

その他

  • 検索しても新しいページがヒットしない場合
    端末から「wwwoffle -status」を実行して「State : offline」になっていればキャッシュを取得しない状態なので「wwwoffle -online」でオンラインにすればキャッシュの取得が実行される。後はHyper Estraierでインデックスを更新してやればよい。
  • Hyper Estraierの検索結果画面の初期状態でフォームにフォーカスを当てない設定
    一般的な話ではないが、FirefoxアドオンVimperatorやChrome拡張Vimium(いずれもキーボードオンリーでブラウザを操作するブラウザ拡張)を使っていて、マウスを使わずにブラウザを操作している場合に、Hyper Estraierの検索結果のページ表示直後の状態だと入力フォームにフォーカスが当たっていて、いちいちEscを押してフォーム入力状態を抜けなくてはならないのが煩わしく感じる。
    これを解決するため、estseek.tmplの295行目を以下のように修正した。この修正をしても、「検索前」の画面では初期状態として入力フォームにフォーカスが当たるままとなるので面倒はない(余談として、元のコードで「#」を数えている箇所があるが、なぜ「#」を数えているのかは分からなかった)。

    <script type="text/javascript">function startup(){
    if((document.location + "").indexOf("phrase") != -1) return; // ←修正
    //  if((document.location + "").indexOf("#") != -1) return;    // ←元
    var elem = document.getElementById("phrase");
    if(elem) elem.focus();
    }
    

課題点など

  • 他の端末から利用する際の不具合
    ローカルネットワークの別のPCからwwwoffleのキャッシュサーバを利用しようとすると著しく反応が遅いが原因不明。時おりローカルホストからのアクセスでも反応が遅いことがあった(→ローカルホストからの反応が遅いのはwwwoffleやpolipoの再起動で改善した)。

    また、スマホやタブレット端末のプロキシにwwwoffleを設定してhttpsのページを閲覧しようとしたところ、iPhoneの場合、Safariでは警告が出て閲覧できたりできなかったり、Firefoxは警告が出て閲覧不能、はてなブックマークアプリも閲覧不能だった。Androidの場合は証明書を入れても閲覧できなかった。このためスマホやタブレットからの利用は断念した。これらは以下の項目と同様に、スマートフォンがwwwoffleの証明書を受け付けないのが原因であると思われる。

  • Chromeから利用する際の不具合
    Chromeで使う際、オプションの「--proxy-pac-url=」で自動プロキシ設定を指定しているが、どうもwwwoffleに接続していないような気がする。Firefoxをメインで使っているのであまり気にしていないが、Chromeを使う場合は検討が必要かもしれない。
    (追記)
    結論としては、現状Chromeからwwwoffleを使うことはできない。
    理由としては、wwwoffleの証明書がChromeの様式と合わないことが原因らしい。
    以下は詳しい内容。

    chrome72ぐらいからproxy-pac-urlにfile://プロトコルを受け付けなくなったらしく、webサーバの公開ディレクトリにproxy.cfgを置いて、http://で記述してやれば接続できる。

    At some point (around Chrome 77 it seems), Chrome stopped accepting file:// URLs for --proxy-pac-url.

    you are probably better either installing a browser plugin that lets you define PAC settings, or use an http(s) PAC file.

    ただし、Chromeでは以下のエラーが出てwwwoffleの自己署名証明書が受け付けられなかった。

    この接続ではプライバシーが保護されません
    yahoo.co.jp では、悪意のあるユーザーによって、パスワード、メッセージ、クレジット カードなどの情報が盗まれる可能性があります。詳細
    NET::ERR_CERT_COMMON_NAME_INVALID
    このサーバーが yahoo.co.jp であることを確認できませんでした。このサーバーのセキュリティ証明書で SAN(サブジェクトの別名)が指定されていません。設定が不適切であるか、悪意のあるユーザーによって接続が妨害されている可能性があります。


    これは、Chromeの仕様変更により、ドメイン名のチェックにSANを使用するようになったからとのこと。

    ローカル環境でhttpsを実現するために、オレオレ(自己署名)SSL証明書を作成したのですがchromeではNET::ERR_CERT_COMMON_NAME_INVALIDとなってしまいました。
    Chromeの仕様変更により、ドメイン名のチェックをCommon Name(通称CN)ではなくSubject Alternative Names(通称SAN)を参考にする様になったためだそうです。


所要時間

調査・設定には10時間を所要した。だが、「自分にパーソナライズされた(閲覧履歴内の)ウェブ全文検索」という利便性は代えがたいものになるだろう。

参照サイト