Jestem naprawdę nowy w Pythonie i utknąłem z poniższym problemem, który muszę rozwiązać. Mam plik dziennika z Apache Log jak poniżej:Dodaj wartości kluczy i posortuj je według występowania kluczy na liście słowników w Pythonie
[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
mam wrócić 10 najbardziej żądanych obiektów i ich skumulowane bajtów przeniesione. Muszę uwzględnić tylko żądania GET z pomyślnymi odpowiedziami (HTTP 2xx).
Więc powyżej dziennika doprowadziłoby do:
/images/ksclogosmall.gif 10905
/images/opf-logo.gif 65022
Do tej pory mam następujący kod:
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)
Ten kod drukuje następującą listę słownika.
[{'/images/opf-logo.gif': 32511},
{'/images/ksclogosmall.gif': 3635},
{'/images/ksclogosmall.gif': 3635},
{'/images/opf-logo.gif': 32511},
{'/images/ksclogosmall.gif': 3635}]
nie wiem jak się do tego zabrać stąd aby uzyskać wynik jak:
/images/ksclogosmall.gif 10905
/images/opf-logo.gif 65022
Wynik ten jest w zasadzie dodanie wartości odpowiadających podobnych kluczy posortowanych według liczby razy wystąpiły szczególności klucz w porządku desc.
Uwaga: Próbowałem używać colllections.Counter bez skutku, tutaj chciałbym sortować według liczby razy, kiedy klucz wystąpił.
Każda pomoc zostanie doceniona.
próbowałem tego, ale to nie jest wh w razie potrzeby. Muszę posortować listę słowników przez liczbę czasu, w którym wystąpił dany klucz, a jednocześnie dodać ich wartości, a ostateczne wyniki będą najwyższe do najniższych, takich jak: /images/ksclogosmall.gif 10905 /images/opf -logo.gif 65022 –
OK, zaktualizowałem swoją odpowiedź. – Imran
Wciąż ten sam, posortowany według wartości. Chcę go posortować według czasu, w którym wystąpił dany klucz, więc mimo że wartość odpowiadająca kluczowi "/images/opf-logo.gif" wynosi 65022 w porównaniu z wartością "/images/ksclogosmall.gif", która wynosi 10905 , nadal powinno być na wierzchu, ponieważ klucz "/images/ksclogosmall.gif" wystąpił 3 razy na liście słowników w porównaniu z drugim, który wystąpił tylko dwa razy. Przepraszam za wszelkie zamieszanie, od jakiegoś czasu utknąłem w tej części. –