PythonでFirefox3の検索履歴にアクセスする
firefox3の検索バーに出てくる履歴の正体はsqliteで管理されたデータらしい。winXPでは、%APPDATA%\Mozilla\Firefox\Profiles\xxxxxxxx.default\formhistory.sqlite
(xxxxxxxxはランダム)のmoz_formhistoryテーブルが直接対応している。
$ sqlite3 formhistory.sqlite sqlite> select * from moz_formhistory; ....(出力)
これで確認できる。
formhistory.sqliteには検索バーからの検索されたキーワードだけでなく、googleのページから検索されたキーワードも記録されていた。Pythonにはsqlite3を扱うモジュールがある。ってことであわせて使ってみた。今のところwinXPのPython2.5.2でしか動作確認していないのでlinuxで動くかどうか分からない。それでも、データベースへの適切なパスを変数dbpathに代入すれば使えるはず。windows98,Meもプロファイルの場所が違うのでdbpathを書き換える必要がある。
参考資料:
プロファイル http://support.mozilla.com/ja/kb/Profiles
プロファイルフォルダの構成 http://support.mozilla.com/ja/kb/%E3%83%97%E3%83%AD%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%81%AE%E6%A7%8B%E6%88%90
#! /bin/python # coding: sjis import sys import os import sqlite3 from glob import glob dbname = "formhistory.sqlite" profpat = "????????.default" # フォームの履歴を保持するsqliteデータベースのパスを判別 pf = sys.platform if pf == "win32": dbpath = os.environ["APPDATA"] + "\\Mozilla\\Firefox\\Profiles\\" dbpath = glob(dbpath+"\\"+profpat)[0] + "\\" + dbname elif pf == "linux": dbpath = "~/.mozilla" dbpath = glob(dbpath+"/"+profpat)[0] + "/" + os.listdir(dbpath)[0] + "/" + dbname # ここまでに変数dbpathにデータベースへのパスをバインドしておく def querywords(): # 検索ワードをリストで返す conn = sqlite3.connect(dbpath) curs = conn.cursor() ncurs = curs.execute("select value from moz_formhistory where fieldname='q' or fieldname='searchbar-history'") ws = [x[0] for x in ncurs.fetchall()] conn.close() return ws def frequency_dictionarize(lst): # {単語: 出現回数}の辞書にする関数 # 英字は小文字化する d = {} for n in lst: keys = n.lower().split() for k in keys: if d.has_key(k): d[k] += 1 else: d[k] = 1 return d def trans(dic): # {単語:出現回数}の辞書を{出現回数:単語}にする d = {} for k in dic.keys(): freq = dic[k] if d.has_key(freq): d[freq].append(k) else: d[freq] = [k] return d def main(): ws = querywords() fdict = frequency_dictionarize(ws) tdict = trans(fdict) # 回数の多い順から内容を表示 for k in sorted(tdict.keys(), lambda x,y: cmp(int(y),int(x))): print k,"|", for n in tdict[k]: print n, print "" if __name__ == '__main__': main()
実行結果
343 | python 168 | haskell 128 | cygwin 118 | c言語 85 | ruby 83 | windows 79 | c 75 | 2ch 74 | c++ opengl 57 | scheme 54 | google 44 | firefox 41 | java 40 | mac 36 | meadow mini 34 | unix インストール 32 | 和英 eeebox 31 | linux 30 | eclipse rails 29 | django 28 | thinkpad glut 27 | プログラミング 26 | 英和 25 | emacs 24 | hopengl tkinter 23 | r31 22 | yahoo mysql 数学 podcast 21 | ダウンロード gui iphone フォント コマンド 20 | the eeepc901 chrome 19 | itunes sqlite 設定 18 | ライブラリ ghc lisp fedora ニュートン法 17 | eeepc プログラム マニュアル on 16 | dell gcc .. (大幅に略)
このプログラムとデータをもとにグラフを書くと面白いかもしれない。あとは、、家族や学生同士で共有しているPCで使うと見てはいけないものが見えるかもしれない。
特徴的だったのは4300ぐらいある単語のうち、2800語ぐらいは1度しか検索されていなかったことで、出力の6割以上が1度しか検索していない単語のリストでかなり長い。その多くは長いキーワードとtypo、それと、単純にあまり調べない事柄に関するキーワードだ。例えば、「無線lan環境に必要なもの」とか、「makeifle」とか(makefile)。
typoが面白い。
- gogoel, gogole (google)
- firefo, fireofx (firefox)
- pyてょn, lython, pytyhon, pythnon, pyton (python)
- めいけろそふと (マイクロソフト)
- じぇねれーt (ジェネレータ)
- ぃぬx (linux)
- zipo (zippo)
- csvとあh, csvとあは (csvとは)
- 刑事場 (掲示板)
- ペアノの小売 (ペアノの公理)
- podcase (podcast)
謎の検索ワードたち
- 退院具
- oidon
- バス飽和
- マルチスレッド朝青龍
マルチスレッド朝青龍って何だ。
(追記:9/13)
Google Chromeでは、C:\Documents and Settings\%USERNAME%\Local Settings\Application Data\Google\Chrome\User Data\Default\Historyがsqliteデータベースになっていて、このデータベースのkeyword_search_termsが履歴を管理するテーブルでした。windowsの場合はこちらも参照して集計するともっと面白いかも。