2015-10-27 5 views
0

Мне нужно обработать файл журнала squid, где каждая строка представляет собой веб-запрос. Файл представляет собой пробел, как любой обычный файл журнала, но также имеет заголовки запросов в последнем столбце. Например,Как читать файл журнала squid с двумя форматами в строке в python

1445210282000 - - - - CONNECT service.gc.apple.com:443 1.1 200 - Host:%20service.gc.apple.com%0D%0AUser-Agent:%20gamed/5.10.19.4.7.16.5.4.2%20(iPhone7,2;%209.0.2;%2013A452;%20GameKit-363.4)%0D%0AConnection:%20keep-alive%0D%0AProxy-Connection:%20keep-alive%0D%0A 

Как было показано выше в последнем столбце имеет различные заголовки запроса в заголовке: Формат значения с 20%,% 0A и другие символы. Мне нужно извлечь каждый заголовок в отдельный столбец для каждой строки, как и другие столбцы.

Что я сделал это:

with open(filename, 'rt') as squidlog: 
    for line in squidlog: 
     cols = line.split() 
     headers = cols[10].split('%0A') 

Но я не уверен, как извлечь переменную headers и иметь все составляющие заголовки, как хост, User-Agent, как только другой столбец в cols (или некоторая лучшая структура данных, такая как dict, кортежи имен и т. д.).

ответ

1

Вы можете попробовать пакет "urllib2",

заголовки = urllib2.unquote (перевалы [-1]). Раскол()

1

Я не уверен, что это лучший способ но я принял ответ nagato и расширил его, чтобы вытащить заголовки и значения в словарь с использованием довольно темной магии регулярного выражения.

import urllib2 
import re 

#regex for extracting header from either start of line or "- " up to a colon 
header_re = re.compile('(?:^|(?:-))([^\s\.:]+):') 

def parseLogLine(t): 
    "Take a squid log line and return a dictionary of header:value" 
    parse_dict = {} 
    #unquote %0A etc to get normal lines chars and split 
    encoded_lines = urllib2.unquote(t).split('\r\n') 

    for l in encoded_lines: 
     #regex match for header 
     m = header_re.search(l) 

     #check we find a match extract the header string 
     #and value string 

     if m is not None: 
      header_key = m.group(1) 
      value = l[m.end():] 
      parse_dict[header_key] = value 

    return parse_dict 

if __name__ == '__main__': 
    #quick test 
    print parseLogLine("""1445210282000 - - - - CONNECT service.gc.apple.com:443 1.1 200 - Host:%20service.gc.apple.com%0D%0AUser-Agent:%20gamed/5.10.19.4.7.16.5.4.2%20(iPhone7,2;%209.0.2;%2013A452;%20GameKit-363.4)%0D%0AConnection:%20keep-alive%0D%0AProxy-Connection:%20keep-alive%0D%0A""") 

Первая часть регулярного выражения (:^| (:? -)) сопрягает либо начало строки "^" или "-" с использованием не-захвата круглых скобок, то [^ \ s.:] + ищет непространственный текст, который не является "." или «:» перед фактическим «:» для соответствия заголовку.

Надеюсь, это поможет.