我有一个日志文件,其中每一行都包含IP地址,访问时间和访问的URL。我想计算每小时的访问次数。
访问时间数据如下所示
[01/Jan/2017:14:15:45 +1000]
[01/Jan/2017:14:15:45 +1000]
[01/Jan/2017:15:16:05 +1000]
[01/Jan/2017:16:16:05 +1000]
如何改进它以便我不需要为每小时设置变量和if语句?
twoPM = 0
thrPM = 0
fouPM = 0
timeStamp = line.split('[')[1].split(']')[0]
formated_timeStamp = datetime.datetime.strptime(timeStamp,'%d/%b/%Y:%H:%M:%S %z').strftime('%H')
if formated_timeStamp == '14':
twoPM +=1
if formated_timeStamp == '15':
thrPM +=1
if formated_timeStamp == '16':
fouPM +=1
答案 0 :(得分:3)
您可以在strptime
格式说明中加入括号:
datetime.datetime.strptime(line.strip(),'[%d/%b/%Y:%H:%M:%S %z]')
您可以使用任何.hour
对象的datetime.datetime
属性提取小时:
timestamp = datetime.datetime.strptime(…)
hour = timestamp.hour
您可以使用collections.Counter
计算元素数量:
from collections import Counter
def read_logs(filename):
with open(filename) as log_file:
for line in log_file:
timestamp = datetime.datetime.strptime(
line.strip(),
'[%d/%b/%Y:%H:%M:%S %z]')
yield timestamp.hour
def count_access(log_filename):
return Counter(read_logs(log_filename))
if __name__ == '__main__':
print(count_access('/path/to/logs/'))
答案 1 :(得分:2)
您没有说每小时访问是每天还是什么。所以有很多方法可以实现。但这是一个简单的版本:
import collections
import io
log_data = '''
[01/Jan/2017:14:15:45 +1000]
[01/Jan/2017:14:15:45 +1000]
[01/Jan/2017:15:16:05 +1000]
[01/Jan/2017:16:16:05 +1000]
'''
def filter_lines(file):
for line in file:
if line.startswith('['):
yield line
def extract_hour_from_line(seq):
for line in seq:
yield line.split(':')[1]
def access_per_hour(file):
aph = collections.Counter(extract_hour_from_line(filter_lines(file)))
return aph
if __name__ == '__main__':
logfile = io.StringIO(log_data)
aph = access_per_hour(logfile)
print(aph)
这使用StringIO将您提供的行作为示例转换为可以读取的内存“文件”。你可以打开你的日志文件,正如你无疑已经做的那样,正常处理这个问题。
collections.Counter类接受一个序列并生成一个类似字典的对象,其中键是序列中的项,值是计数 - 每个序列中出现的次数。
此版本的代码只计算所有不同的小时值,而不考虑访问发生的 date 。也就是说,周二的12:00和周三的12:00被视为同一小时。如果您只是构建按小时需求的直方图,这非常有用。
如果您想进行更高级的分组,可以尝试使用filter_lines
功能来限制您想要查看的整行。例如,仅限日期范围之间的行,或仅访问特定URL的行。
如果您希望将不同日期视为不同日期,则可以使用extract_hour_from_line
函数构造不同的值 - 例如,连接日期和小时。
答案 2 :(得分:1)
您可以使用字典:
per_hour = {}
per_hour[formated_timeStamp] += 1
所以你会得到一些东西
{'0': 12, '1': 8, '2': 41, ...}
其中键代表一小时。