年齢ともに記憶が弱ってくると、ちょっと前にやったことを忘れがちです。あれこれ調べ物をしていると、数時間前に見たはずのWebサイトの記憶が全くない時があります。
ブラウザの履歴からもう一度アクセスするとさすがに思い出すのですが、見直すまですっかり忘れてしまっているという。なんとも困ったものです。
自分の記憶の補助にブラウザのログを使おうと思います。朝起きたら前日に閲覧していたサイトの要約を書き出して見直す、そんな作業をPythonにやってもらおうと思います。
この記事では、Pythonを使って自動でWeb閲覧ログを収集・分析する事について述べます。
ブラウザ履歴でライフログ?
簡単にまとめると: 年齢と共に「以前見たはずのWebサイト」を思い出せなくなるのは、記憶を定着させる脳の働きが自然に変化するためです。この変化を補うため、Pythonでブラウザ履歴を自動的に記録・要約し、「外部の記憶装置」として活用することで、判断ミスを減らし、日々の生産性を高めることができます。
その根拠とは?:
- 記憶と加齢: 睡眠中の記憶固定化は加齢で効率が落ちることが分かっています (Mander et al., 2017)。ノンレム睡眠が短いこと、これが「あれ、何だっけ?」の一因と言われています。
- 外部記憶の有効性: 高齢者は重要な情報ほど、メモ等に記録(オフロード)して記憶を補う戦略をとる傾向があります (Murphy & Castel, 2023)。これは脳の負荷を減らす賢い方法です。
- 自動記録の威力: 日常を自動撮影する「ライフログ」を見返すだけで、記憶障害のある人でも8割以上の出来事を思い出せたという研究があります (Hodges et al., 2006)。文字より具体的な視覚情報が、記憶を強力に引き出すのです。
その方法: 毎朝、前日に閲覧したサイトのURL、タイトル、滞在時間を集計し、特に重要なページの本文を自動で要約して一覧化します。この「Web閲覧日報」をMarkdownファイルとして保存することで、昨日自分が何に興味を持ち、何を考えていたかを数分で見返すことができます。
決意: 自分の記憶力に頼るのではなく、「記録」を賢く使うことで、年齢による変化にスマートに対応し、知的好奇心を維持し続けたい!
実際にやってみよう!
ここからは、実際にPythonを使ってブラウザの閲覧履歴を読み込み、Markdown形式の日報を作成する手順を解説します。macOS環境を例に進めますが、WindowsやLinuxでも基本的な考え方は同じです。
まずは準備その1:Macに“アクセス許可”をあげる
macOSでは、セキュリティ上の理由から、アプリケーションが他のアプリケーションのデータ(ブラウザ履歴など)にアクセスすることは厳しく制限されています。そのため、Pythonスクリプトを実行する環境(ターミナルやVSCodeなど)に「フルディスクアクセス」を手動で許可してあげる必要があります。
- システム設定を開く:
- 画面左上のアップルメニューから「システム設定」を選択します。
- プライバシーとセキュリティへ移動:
- 左側のサイドバーで「プライバシーとセキュリティ」をクリックします。
- フルディスクアクセスを選択:
- 右側のリストから「フルディスクアクセス」を探してクリックします。
- アプリケーションを追加:
python3を選択できない場合は、 ⌘ + Shift + G
で直接パスを入力すると指定することが出来ました。
これで、Pythonスクリプトがブラウザの履歴データベースにアクセスする準備が整いました。
準備その2:Pythonで履歴をのぞいてみる
Chromeの閲覧履歴は、History
という名前のSQLiteデータベースファイルに保存されています。macOSでのパスは以下の通りです。
~/Library/Application Support/Google/Chrome/Default/History
このデータベースにPythonから接続し、SQLクエリを使って情報を抽出します。
コードを書いてみよう!(AIに書いてもらおう!)
以下のPythonコードは、直近24時間以内に閲覧したサイトのURLとタイトルを取得し、Markdown形式で出力するサンプルです。
▶ クリックでコードが開きます
'''python import sqlite3 import os import datetime as dt import tempfile import shutil from pathlib import Path
def chrome_history_path(profile="Default"): return os.path.expanduser( f"~/Library/Application Support/Google/Chrome/{profile}/History" )
def to_chrome_timestamp_utc(dt_utc: dt.datetime) -> int: # Chrome/WebKit epoch (UTC) epoch = dt.datetime(1601, 1, 1, tzinfo=dt.timezone.utc) return int((dt_utc - epoch).total_seconds() * 1_000_000)
def from_chrome_timestamp_utc(microsec: int) -> dt.datetime: epoch = dt.datetime(1601, 1, 1, tzinfo=dt.timezone.utc) return epoch + dt.timedelta(microseconds=microsec)
def get_recent_history(hours=24, profile="Default"): src = chrome_history_path(profile) if not os.path.exists(src): raise FileNotFoundError(f"History DB not found: {src}")
# DBロック回避:一時ファイルにコピーして読む
tmpdir = tempfile.mkdtemp(prefix="chrome_history_")
tmpdb = os.path.join(tmpdir, "History")
shutil.copy2(src, tmpdb)
conn = None
try:
conn = sqlite3.connect(tmpdb)
cur = conn.cursor()
# 直近hours時間(UTC基準)
cutoff_utc = dt.datetime.now(dt.timezone.utc) - dt.timedelta(hours=hours)
cutoff_chrome = to_chrome_timestamp_utc(cutoff_utc)
# URL, タイトル, 訪問時刻(新しい順)
cur.execute("""
SELECT urls.url, urls.title, visits.visit_time
FROM urls
JOIN visits ON urls.id = visits.url
WHERE visits.visit_time > ?
ORDER BY visits.visit_time DESC
""", (cutoff_chrome,))
rows = cur.fetchall()
return rows
finally:
if conn:
conn.close()
# 片付け
try:
shutil.rmtree(tmpdir)
except Exception:
pass
def write_markdown_report(rows, outfile_path: Path): # 表示はローカル時刻(日本)へ jst = dt.timezone(dt.timedelta(hours=9)) today = dt.datetime.now(jst).strftime("%Y-%m-%d") md = [f"# {today} のブラウジング日報\n"]
if not rows:
md.append("- (直近の閲覧はありません)\n")
else:
for url, title, vtime in rows:
visited_utc = from_chrome_timestamp_utc(vtime)
visited_local = visited_utc.astimezone(jst)
tstr = visited_local.strftime("%H:%M")
label = title if (title and title.strip()) else url
md.append(f"- [{label}]({url}) - {tstr}\n")
outfile_path.write_text("".join(md), encoding="utf-8")
return outfile_path
if name == "main": try: rows = get_recent_history(hours=24, profile="Default") out = Path.cwd() / f"{dt.datetime.now().strftime('%Y-%m-%d')}_browser_report.md" write_markdown_report(rows, out) print(f"レポートを作成しました: {out}") except sqlite3.OperationalError as e: print("SQLiteの操作でエラーが発生しました。Chromeを起動したままにしていませんか?") print(f"詳細: {e}") except Exception as e: print(f"エラー: {e}")
'''
コードのポイント(簡易版)
DBアクセス
sqlite3
でChromeの履歴DBを読む。- 直接開くとロックされるので、一度コピーしてから接続。
時刻の扱い
SQLクエリ
urls
とvisits
をJOINして、直近24時間の履歴を新しい順に取り出す。
Markdown出力
- 日付見出し+「タイトル(リンク) - 時刻」のリストで保存。
- タイトルが空ならURLを代わりに使う。
エラーハンドリング
- DBが見つからない/ロックされている場合はメッセージ表示。
finally
で接続を閉じ、一時ファイルを掃除。
👉 このコードを動かすと、「昨日どのサイトを何時に見ていたか」をMarkdown形式の日報として残せます。
アウトプット例
# 2025-09-01 のブラウジング日報 - [PythonでChromeの履歴を読む方法 – Qiita](https://qiita.com/xxxx) - 20:31 - [Chrome SQLite schema | Chromium docs](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/components/history) - 20:15 - [Stack Overflow – sqlite OperationalError database is locked](https://stackoverflow.com/questions/xxxxxx) - 19:58 - [(タイトルなし)](https://127.0.0.1:xxxx/debug) - 19:40
ちょっとしたコツと気をつけたいこと
参考に:ライフログってこんな考え方
この記事ではブラウザ履歴を扱いましたが、より広範に「自分の生活を記録する」という考え方は「ライフログ」と呼ばれ、記憶を補う有効な手段として知られています。
かつて(2004年)、日常を自動で撮影するカメラがありました。Microsoftが開発したSenseCamというカメラを用いた記憶障害の方への研究で、写真を見返すだけで記憶が大幅に改善する結果が示されました。これは、文字情報よりも具体的な「視覚的な手がかり」が、記憶を強力に引き出すことを意味しています。
論文を200字にまとめてみた
Hodges et al., 2006
SenseCamは記憶補助を目的としたウェアラブルカメラとして開発され、光や温度、加速度などのセンサーで自動撮影を行い、日常を記録します。初期の臨床試験では、健忘症患者がSenseCamの画像を繰り返し閲覧することで、数日で失われていた自伝的記憶が長期間保持される効果が確認されました。特に1年間にわたる試験では、イベントから数か月経っても高い想起率を維持でき、従来の日記よりも有効とされました。自動で記録される点が、記憶障害者にとって大きな利点と結論づけられています。
現在では、もっと手軽にスマートフォンで日常の何気ない風景や作業内容を写真に撮っておくことでも、同様の効果が期待できるでしょう。「あの時、何をしていたかな?」と思った時に、写真フォルダを眺めるだけで、忘れていた文脈を鮮明に思い出せるかもしれません。
この記事で提案した「ブラウザ履歴の日報」は、このライフログの考え方を、PC上での知的活動に特化させた、誰でも始めやすい第一歩と位置づけることができます。
ここだけは注意!プライバシーと道具の付き合い方
一方で、このアプローチには限界と注意点もあります。
最も重要なのはプライバシーの問題です。ブラウザ履歴は、その人の興味、悩み、人間関係など、極めて個人的な情報を含みます。今回作成したスクリプトで得られるデータも、取り扱いには最大限の注意が必要です。他人のPCで実行したり、得られたデータを安易に外部に送信したりすることは絶対に避けるべきです。
また、こうしたツールはあくまで「記憶の補助」です。記憶力の低下そのものを治療するものではなく、ツールに頼りすぎることで、かえって自力で記憶しようとする意識が低下する可能性も指摘されています。
最終的には、テクノロジーを賢く活用しつつも、健康的な生活習慣や、人との対話といった、脳の健康を保つための基本的な取り組みとバランスを取ることが大切です。
まとめ:今日からできる小さな一歩
今日から“1つだけ”やるなら:まずは、お使いのブラウザの履歴がどこに保存されているか、そのフォルダを覗いてみることから始めてみましょう。