网络服务器 Apache 和 Nginx 都可以通过 mod_unique_id/userid 模块为访问者提供 uniqid cookie。这样的cookie looks like四个 uint32 值编码为 base64 字符串。第二个字节是 cookie 发出时的时间戳。
我想提取它的日期和时间。
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])
最佳答案
我不知道“人工”和“pythonic”到底是什么意思,但至少在我的机器上,该代码是不正确的。它在某种程度上是不正确的,会给您提供可能不会被注意到的虚假数据。
unpack
的 'IIII'
格式代码未指定字节顺序,这在我的 (x86) 计算机上会导致错误的时间戳。 documentation说省略字节顺序将导致它默认为您机器的字节顺序。但在 mod_uid 版本 2 中,cookie 使用网络字节顺序。使用格式代码 !IIII'
指定网络字节顺序。
如果“pythonic”是指将其分散在几行中而不是打包成一行,那么它的外观如下:
binary_cookie = b64decode(raw_cookie)
fields = unpack('!IIII', binary_cookie)
visit_date = datetime.fromtimestamp(fields[1])
关于python - 从 apache/nginx 用户 id cookie 中提取日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41588906/