Python で HAR ファイルから散布図を作成
Web サイトの構成を可視化するため、Python で HAR (HTTP ARchive) ファイルをパースし散布図を試しに作ってみました。
今回作成した散布図の内容は以下の通りです。
- 横軸は time (処理時間 (ミリ秒))
- 縦軸は bodySize (レスポンスボディのサイズ)
- MIME タイプのサブタイプ別に色分け
今回は Anaconda に予め含まれているライブラリを使用する事にします。
今回のソースは http://github.com/fits/try_samples/tree/master/blog/20170514/
はじめに
HAR ファイルは Chrome や Firefox の開発ツールで取得できますが、簡易なものは PhantomJS の examples/netsniff.js
で取得できるので今回はこれを使いました。
HAR の取得
phantomjs netsniff.js <URL>
netsniff.js では console.log
で HAR の内容を出力するようになっています。
HAR ファイルの取得例
phantomjs netsniff.js https://www.・・・ > a.har
HAR ファイルは以下のような JSON 形式のファイルとなっています。
HAR ファイル例
{ "log": { ・・・ "entries": [ { ・・・ "time": 4474, "request": { ・・・ }, "response": { ・・・ "bodySize": 473, "content": { "size": 473, "mimeType": "text/html;charset=UTF-8" } }, "cache": {}, "timings": { ・・・ "wait": 3813, "receive": 661, "ssl": -1 }, ・・・ }, ・・・ ] } }
netsniff.js では、timings 内の wait と receive 以外の値は固定値(0 か -1)が設定されるようになっています。
1. seaborn の pairplot 使用
まずは、seaborn の pairplot
を使って散布図を描画してみます。 (pairplot はデフォルトが散布図になっているようです)
pairplot は基本的にデータ内の数値変数の全ての組み合わせをグラフ化するものですが、x_vars
と y_vars
を指定する事で特定の組み合わせに限定したグラフだけを描画する事も可能です。
色分けする項目は hue
で指定できるようになっています。
複数のグラフをグリッド表示する事を想定しているため、個々のグラフのデフォルトサイズが小さく設定されていますが、size
で変更する事が可能です。
har_scatter_plot1.py
import sys import json import codecs import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # HAR ファイルの読み込みと Python オブジェクト化 data = json.load(codecs.open(sys.argv[1], 'r', 'utf-8')) to_subtype = lambda mtype: mtype.split(';')[0].split('/')[-1] # 特定の項目を抜き出す処理 convert = lambda d: { 'subType': to_subtype(d['response']['content']['mimeType']), 'bodySize': d['response']['bodySize'], 'time': d['time'] } # DataFrame 化 df = pd.DataFrame(list(map(convert, data['log']['entries']))) # 散布図の描画 sns.pairplot(df, hue = 'subType', x_vars = 'time', y_vars = 'bodySize', size = 10) imgfile = "%s_1.png" % sys.argv[1] # グラフの保存 plt.savefig(imgfile)
実行例
python har_scatter_plot1.py a.har
実行結果例
a.har_1.png
b.har_1.png
2. サブタイプ毎に plot
pairplot の結果ではサブタイプ毎の色が固定されておらず、複数の Web ページを比較する用途には適していません。
そこで、サブタイプ毎の散布図を重ねて描画してみました。
har_scatter_plot2.py
import sys import json import codecs import pandas as pd import matplotlib.pyplot as plt ・・・ # サブタイプと色のマッピング color_map = { 'javascript': 'blue', 'x-javascript': 'blue', 'json': 'green', 'gif': 'tomato', 'jpeg': 'red', 'png': 'pink', 'html': 'lime', 'css': 'turquoise' } df = pd.DataFrame(list(map(convert, data['log']['entries']))) ax = plt.figure().add_subplot(1, 1, 1) for (k, c) in color_map.items(): # 指定サブタイプのデータを抽出 sdf = df[df['subType'] == k] if not sdf.empty: # c の色で散布図(scatter)を描画 sdf.plot('time', 'bodySize', 'scatter', ax, c = c, label = k) imgfile = "%s_2.png" % sys.argv[1] plt.savefig(imgfile)
実行例
python har_scatter_plot2.py a.har
実行結果例
a.har_2.png
b.har_2.png