Я действительно новичок в Python, и я застрял в этой проблеме, которую мне нужно решить. У меня есть файл журнала из Apache Log, как показано ниже:
[01/Aug/1995:00:54:59 -0400] "GET /images/opf-logo.gif HTTP/1.0" 200 32511
[01/Aug/1995:00:55:04 -0400] "GET /images/ksclogosmall.gif HTTP/1.0" 200 3635
[01/Aug/1995:00:55:06 -0400] "GET /images/ksclogosmall.gif HTTP/1.0" 403 298
[01/Aug/1995:00:55:09 -0400] "GET /images/ksclogosmall.gif HTTP/1.0" 200 3635
[01/Aug/1995:00:55:18 -0400] "GET /images/opf-logo.gif HTTP/1.0" 200 32511
[01/Aug/1995:00:56:52 -0400] "GET /images/ksclogosmall.gif HTTP/1.0" 200 3635
Я должен вернуть 10 наиболее запрошенных объектов и их накопленные байты. Мне нужно включить только GET-запросы с успешными (HTTP 2xx) ответами.
Таким образом, приведенный выше журнал приведет к:
/images/ksclogosmall.gif 10905
/images/opf-logo.gif 65022
До сих пор у меня есть следующий код:
import re
from collections import Counter, defaultdict
from operator import itemgetter
import itertools
import sys
log_file = "web.log"
pattern = re.compile(
r'\[(?P<date>[^\[\]:]+):(?P<time>\d+:\d+:\d+) (?P<timezone>[\-+]?\d\d\d\d)\] '
+ r'"(?P<method>\w+) (?P<path>[\S]+) (?P<protocol>[^"]+)" (?P<status>\d+) (?P<bytes_xfd>-|\d+)')
dict_list = []
with open(log_file, "r") as f:
for line in f.readlines():
if re.search("GET", line) and re.search(r'HTTP/[\d.]+"\s[2]\d{2}', line):
try:
log_line_data = pattern.match(line)
path = log_line_data["path"]
bytes_transferred = int(log_line_data["bytes_xfd"])
dict_list.append({path: bytes_transferred})
except:
print("Unexpected Error: ", sys.exc_info()[0])
raise
f.close()
print(dict_list)
Этот код печатает следующий список словарей.
[{'/images/opf-logo.gif': 32511},
{'/images/ksclogosmall.gif': 3635},
{'/images/ksclogosmall.gif': 3635},
{'/images/opf-logo.gif': 32511},
{'/images/ksclogosmall.gif': 3635}]
Я не знаю, как это сделать, чтобы получить результат:
/images/ksclogosmall.gif 10905
/images/opf-logo.gif 65022
Этот результат в основном добавляет значения, соответствующие аналогичным ключам, отсортированным по количеству раз, когда конкретный ключ произошел в порядке desc.
Примечание. Я попытался использовать colllections.Counter без каких-либо изменений, здесь я бы хотел сортировать по количеству раз, когда произошел ключ.
Любая помощь будет оценена.