2017-01-11 5 views
1

ApacheとNginxの両方のWebサーバーは、訪問者にmod_unique_id/useridモジュールを使用してuniqid cookieを与えることができます。そのようなcookie looks like 4つのuint32値は、base64文字列にエンコードされます。 2番目のバイトは、Cookieが発行されたときのタイムスタンプです。apache/niginxのユーザーIDクッキーの日付を抽出します

私はその日時を抽出したいと思います。

from base64 import b64decode 
from datetime import datetime 
import shlex, gzip, glob 
from struct import unpack 

import pandas as pd 
import numpy as np 


def get_data() -> pd.DataFrame: 
    filenames = glob.glob('data/user_cookie/stat-*.gz') 
    for filename in filenames: 
     print(filename) 
     f = gzip.open(filename, 'rt') 
     for row in f.readlines(): 
      parts = shlex.split(row) 
      useragent, raw_cookie = parts[9], parts[16] 
      if raw_cookie == '-': 
       raw_visit_date = parts[3][1:] 
       # this is a first visit 
       visit_date = datetime.strptime(raw_visit_date, 
               '%d/%b/%Y:%H:%M:%S') 
      else: 
       visit_date = datetime.fromtimestamp(unpack('IIII', 
                  b64decode(raw_cookie))[1]) 
      print(useragent, visit_date) 


if __name__ == '__main__': 
    get_data() 

この行は特に私には "人工的"と思われます。どのようにすべてのコードをより "pythonic"かつ高速にするか?

datetime.fromtimestamp(unpack('IIII', b64decode(raw_cookie))[1]) 

答えて

1

「人工的」と「pythonic」という言葉は正確には分かりませんが、少なくとも私のマシンではそのコードは間違っています。気付かれないかもしれない偽のデータを与える方法では間違っています。

unpack'IIII'のフォーマットコードでは、バイトオーダーが指定されていません。このオーダーは、自分のマシン(x86マシン)でタイムスタンプが正しくありません。 documentationでは、バイトオーダーを省略すると、マシンのバイトオーダーがデフォルトになります。しかし、mod_uidバージョン2では、クッキーはネットワークバイトオーダーを使用します。フォーマットコード!IIII'でネットワークバイトオーダを指定します。

「神託」あなたの代わりに1にそれを梱包の数行を渡ってそれを広める意味でならば、ここでそれがどのように見えるかです:

binary_cookie = b64decode(raw_cookie) 
fields = unpack('!IIII', binary_cookie) 
visit_date = datetime.fromtimestamp(fields[1]) 
関連する問題