Pandasを使用してWebサイトのアクセスログを分析

6266 ワード

Pandasを用いたApacheアクセスログ解析の例を示します.本文の内容は、Pandasライブラリに対する原作者の試みでもある.
1、データのロードと解析
Webサイトのログを解析するにはapachelogモジュールが必要です.そのため、まずApache構成のログ関連フォーマットを理解する必要があります.ここでは詳細に展開するつもりはありません.興味があれば、公式に提供されているフォーマットの説明を詳しく参照してください.ここでは、Apache構成フォーマットについて簡単に説明します.ここで、すべての要素は次の文にまとめることができます.
format = r’%V %h %l %u %t\”%r\” %>s %b\”%i\”\”%{User-Agent}i\” %T’
ここで、各記号の組み合わせの具体的な意味は以下の通りである(詳細はここを参照).
%V-UseCanonicalNameによって設定されたサーバ名%h-リモートホスト(すなわちクライアントIP)%l-identdによって決定されたユーザID(これは信頼性が低いためよくない)%u-HTTP認証によって決定されたユーザ名%t-サーバが処理要求を完了した回数%r-クライアント要求行("GET/HTTP/1.0")%>s-サーバからクライアントに送信されたステータスコード(200,404など)%b-クライアントに対する応答のサイズ(バイト単位)"%i"-対応するURL User-agent-ブラウザの識別文字列%T-Apache要求時間を参照
%matplotlib inline
import sys
import apachelog

フォーマット:
fformat = r'%V %h %l %u %t\"%r\"%>s %b \"%i\" \
"%{User-Agent}i\" %T'

解析の作成:
p = apachelog.parser(fformat)

例文字列:
koldunov.net 85.26.235.202 - - [16/Mar/2013:00:19:43 +0400] “GET/?p=364 HTTP/1.0” 200 65237 “http://koldunov.net/?p=364” “Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11” 0
sample_string = 'koldunov.net 85.26.235.202\
- -[16/Mar/2013:00:19:43 +0400] \
"GET /?p=364 HTTP/1.0" \
200 65237 "http://koldunov.net/?p=364" \
"Mozilla/5.0 (Windows NT 5.1) \
AppleWebKit/537.11 (KHTML, like Gecko) \
Chrome/23.0.1271.64 Safari/537.11" 0'
data = p.parse(sample_string)
data

解析器が正常に動作しているようですが、次に、より多くの実際のデータをロードしましょう(サンプルファイルダウンロードアドレス:アドレス1アドレス2):
log = open('access_log_for_pandas').readlines()

ターゲットファイルの各行を解析し、多くの辞書で構成されたリストとして保存します.
log_list = []
for line in log:
       try:
          data = p.parse(line)
       except:
          sys.stderr.write("Unable to parse %s" % line)
       data['%t'] = data['%t'][1:12]+' '+data['%t'][13:21]+' '+data['%t'][22:27]

       log_list.append(data)

このケースでは、時間のフォーマットを少し調整する必要があります.そうしないと、Pandasは正確に解析できません.
2、データ枠の構築と調整
上記の手順では、辞書で構成されたリストを取得し、次にデータ・ボックスに変換します.
import pandas as pd
import numpy as np
from pandas import Series, DataFrame, Panel
df = DataFrame(log_list)

次に、私たちが得たデータ・ボックスを示します.このデータ・ボックスの最初の2行を見てみましょう.
df[0:2]

解析でデータのすべてのフィールドを使用する必要はありません.次に、使用できない列を削除します.
del df['%T']; del df['%V']; del df['%i']; del df['%l']; del df['%u']; del df['%{User-Agent}i']

また、残りの列名を変更して、より理解しやすくします.
df = df.rename(columns={'%>s': 'Status', '%b':'b', 
                        '%h':'IP', '%r':'Request', '%t': 'Time'})

このデータ・ボックスの最初の5行を見てみましょう.すでにはっきりしています.
df.head()

次に、時間列Timeをdatetime形式に変換し、シーケンス番号を付ける必要があります(以下、呼び出すpop関数は元のTime列を削除します).
df.index = pd.to_datetime(df.pop('Time'))

変数Statusは文字列型のデータである必要があります.変換します.
df['Status'] = df['Status'].astype('int')

変数bの列には文字列'-'が現れることがあるので、この列を処理するときにastypeを使用することはできません.
df['b'][93]

‘-‘
すべての横棒をNaNに変換し、浮動小数点数だけを残し、その単位をバイトからメガバイトに変換する関数を独自に構築できます.
def dash2nan(x):
    if x == '-':
        x = np.nan
    else:
        x = float(x)/1048576.

    return x
df['b'] = df['b'].apply(dash2nan)

上記のフォーマットの調整をよりクールな方法で実現できる人がいるに違いありません:)
以上はデータのロードと前処理の過程で、原文は比較的に長くて、先にここまで運んで、後続は流量分析、サーバーの状態分析などの可視化の過程があって、時間があって引き続き分かち合うことができて、興味のある学生も直接数析学院に行って原文を見て、pandasの基礎の段階の課程のパッケージ