Google Chromeの履歴をExcelに出力する

Google Chromeの履歴をExcelに出力したかったので、Pythonで実装してみた。


**流れは以下の通り。**
1. [Chromeの履歴データをダウンロードする](#履歴のダウンロード)
1. [JSON形式の履歴データを読み込む](#履歴データを読み込んで操作する)
1. [JSONからDataFrameに変換する](#履歴データを取り出す)
1. [必要に応じてタイプスタンプを日時に変換する](#タイムスタンプの変換)
1. [Excelファイルに出力する](#保存)


# 履歴のダウンロード
サイトの指示に従ってGoogle データをダウンロードする。数ステップのみでダウンロードまで完了する。

https://support.google.com/accounts/answer/3024190?sjid=4344168028719459208-AP

出力できるデータの一覧から**Chrome**を選ぶ。形式は`JSON`で出力される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655949/805c30cb-b545-f188-9863-17cac5c6f11f.png)
全期間の履歴を出力したかったが1年間分だけだった。（仕様なのか、1年前に自分で消去したのかは不明・・・）
# Pythonで履歴データをExcelに変換する

## 履歴データを読み込んで操作する
インポート
```python
import json
import datetime
import pandas as pd
```

JSONファイルを開いて辞書データに変換する。
```python
json_open = open('./履歴.json', 'r')
json_load = json.load(json_open)
```

JSONの一番目の階層は、`'Browser History'` `'Session'` `'Typed Url'`になっている。
検索履歴は`'Browser History'` に入っている。
```python
# 以下でそれぞれを出力できる
json_load['Browser History']
json_load['Session']
json_load['Typed Url']
```
`'Browser History'` の中はリスト型になっているので、`len()`で保存されている履歴の全件数を表示できる。
```python
len(json_load['Browser History'])
```
```
107301
```

また、位置を指定して個別の履歴を出力できる。また、個別の履歴は辞書型になっている。
```python
json_load['Browser History'][104]
```
```:出力
{'favicon_url': 'https://cdn.qiita.com/assets/favicons/public/production-c620d3e403342b1022967ba5e3db1aaa.ico',
 'page_transition': 'LINK',
 'title': 'Qiita',
 'ptoken': {},
 'url': 'https://qiita.com/',
 'client_id': '#######################',
 'time_usec': 1706421989661794}
 ```

## 履歴データを取り出す

辞書データから`['Browser History']`の情報をリストに書き出すための関数を定義する。
```python
def json_to_list(input):
    output = [#input['favicon_url'],
            input['page_transition'],
            input['title'],
            input['ptoken'],
            input['url'],
            input['client_id'],
            input['time_usec']]

    return output
```

## 関数を実行し、DataFrameに変換する
10万行近くあるデータなので、`for`文で繰り返すと時間がかかって効率が悪い。そこで、**`map`関数を用いて効率的に**データを取り出す。
`map`関数の戻り値である`mapオブジェクト`はイテレータなので、そのままではなく`list()`でリスト型にした上で、DatafFrameに変換する。列名は、元データの通りに設定する。

```python
g = map(json_to_list, json_load['Browser History'])
col = ['page_transition', 'title', 'ptoken', 'url', 'client_id', 'time_usec']
df_all = pd.DataFrame(list(g), columns=col)
```


## 時刻とサイト名、URLだけを取り出す

新たなDataFrameを作成し、時刻とサイト名、URLだけを取り出す。
以下では、`'time_usec'` `'title'` `'url'`に対応する列を、`.iloc[:,[1,3,5]]]`で取り出している。
```python
col = ['time_usec', 'date', 'time', 'title', 'url']
df_time = pd.DataFrame(columns=col)

df_time = pd.concat([df_time, df_all.iloc[:,[1,3,5]]])
```

### タイムスタンプの変換

UNIX時間で記録されているので、これを普通の日付、時間表示に変換するための関数を定義する。タイムスタンプはマイクロ秒単位で記録されているので、引数に渡す際に`/1000/1000`することに注意。


```python
def conv_date(time_usec):
    dtime = datetime.datetime.fromtimestamp(
        time_usec / 1000 / 1000, datetime.timezone(datetime.timedelta(hours=9)))
    return dtime.strftime('%Y/%m/%d')


def conv_time(time_usec):
    dtime = datetime.datetime.fromtimestamp(
        time_usec / 1000 / 1000, datetime.timezone(datetime.timedelta(hours=9)))

    return dtime.strftime('%H:%M:%S')
```

`apply`メソッドを用いて変換を実行する。
```python
df_time.loc[:,'date'] = df_time.iloc[:,0].apply(conv_date)
df_time.loc[:,'time'] = df_time.iloc[:,0].apply(conv_time)

df_time
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655949/7318cb4b-431e-f9f9-82a2-0571d26f344b.png)

### 保存
CSVだと文字化けするのでExcelファイルに保存する。
```python
df_all.to_excel('chrome_history_all.xlsx')
df_time.to_excel('chrome_history_time.xlsx')
```