В логе каждый клиентский запрос представлен отдельной строкой, поэтому для чтения файла лога удобно воспользоваться конструкцией Python наподобие следующей:
log = open('/usr/local/apache/logs/access_log')
for request in log.readlines():
...
Естественно, не обязательно каждый раз обрабатывать весь файл, можно начать с первой строки, появившейся с момента последнего запуска скрипта. Для этого в конце каждой сессии нужно запоминать номер строки, например, в текстовом файле. Тогда следующую сессию можно начать с этой строки:
start = int(open('last').readline())
for request in log.readlines()[start:]:
...
Элементы в строке запроса разделяются пробелами. Так как в некоторых элементах могут содержаться пробелы (например, типичное содержание поля User-Agent такое: "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"), они берутся в кавычки. Поэтому имеет смысл сначала преобразовать строку в кортеж, используя в качестве разделителя ", а затем уже полученные элементы кортежа снова разбить на кортежи, определив разделителем пробел. Это делается методом split():
>>> request='62.110.7.82 - - [13/Sep/2002:14:19:58 +0400] "GET /demo.htm HTTP/1.1" 200 7297 "http://www.contourcomponents.com/ccactivex.htm" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"'
>>> req1 = request.split('"')
>>> req1
['62.110.7.82 - - [13/Sep/2002:14:19:58 +0400] ', 'GET /demo.htm HTTP/1.1', ' 200 7297 ', 'http://www.contourcomponents.com/ccactivex.htm', ' ', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)', '']
В полученном кортеже нас интересуют:
-
req1[0] - ip адрес и дата (еще два элемента - ident и authuser, представленные "-" игнорируем)
-
req1[1] - запрос пользователя
-
req1[2] - код состояния, количество переданных байт
-
req1[3] - адрес страницы, с которой пришел клиент
-
req1[5] - браузер клиента
Теперь нужно вытащить нужные элементы запроса, снова применив split(), но уже с разделителем-пробелом:
>>>> #получаем ip и дату
...
>>>> req2 = req1[0].split()
>>>> req2
['62.110.7.82', '-', '-', '[13/Sep/2002:14:19:58', '+0400]']
>>>> ip = req2[0]
>>>> date = req2[3][1:]
>>>> date
'13/Sep/2002:14:19:58'
>>>> #получаем запрос клиента. Метод запроса и протокол нас не интересуют, поэтому:
...
>>>> user_request = req1[1].split()[1]
>>>> user_request
'/demo.htm'
>>>> #получаем код состояния и количество байт
...
>>>> status, bytes = req1[2].split()
>>>> status
'200'
>>>> bytes
'7297'
>>>> #получаем ссылающийся адрес и браузер
...
>>>> referer = req1[3]
>>>> browser = req1[5]
Кстати, browser можно также разделить, и получить название браузера и операционную систему клиента, а из referer извлечь, например, поисковые слова.