2016-08-17 62 views
2

我使用Python 3 CSV Reader将一些网页日志文件读入namedtuple。 我无法控制日志文件结构,并且存在各种类型。用Python处理网页日志文件为CSV

分隔符是空格(),问题是某些日志文件格式在时间戳记中放置了一个空格,如下面的日志文件2所示。 CSV阅读器然后将日期/时间戳记作为两个字段来读取。

日志文件1

73 58 2993 [22/Jul/2016:06:51:06.299] 2[2] "GET /example HTTP/1.1" 
13 58 224 [22/Jul/2016:06:51:06.399] 2[2] "GET /example HTTP/1.1" 

日志文件2个

13 58 224 [22/Jul/2016:06:51:06 +0000] 2[2] "GET /test HTTP/1.1" 
153 38 224 [22/Jul/2016:06:51:07 +0000] 2[2] "GET /test HTTP/1.1" 

日志文件通常具有方形引号内的时间戳,但我无法找到应对他们为“引号”的方式。最重要的是,方括号并不总是作为日志中的引号使用(请参阅稍后日志中的[2])。

我已阅读了Python 3 CSV Reader documentation,包括关于方言,但似乎没有任何东西可以处理封闭的方括号。

我该如何自动处理这种情况?

回答

1

这样做,你需要使用正则表达式来代替sep。
例如,这将解析nginx的日志文件为pandas.Dataframe

import pandas as pd 

df = pd.read_csv(log_file, 
       sep=r'\s(?=(?:[^"]*"[^"]*")*[^"]*$)(?![^\[]*\])', 
       engine='python', 
       usecols=[0, 3, 4, 5, 6, 7, 8], 
       names=['ip', 'time', 'request', 'status', 'size', 'referer', 'user_agent'], 
       na_values='-', 
       header=None 
       ) 

编辑:

line = '172.16.0.3 - - [25/Sep/2002:14:04:19 +0200] "GET/HTTP/1.1" 401 - "" "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.1) Gecko/20020827"' 
regex = '([(\d\.)]+) - - \[(.*?)\] "(.*?)" (\d+) - "(.*?)" "(.*?)"' 

import re 
print re.match(regex, line).groups() 

输出将与6条信息

('172.16.0.3', '25/Sep/2002:14:04:19 +0200', 'GET/HTTP/1.1', '401', '', 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.1) Gecko/20020827') 
+0

我是一个元组猜测这需要熊猫图书馆。很高兴知道这是可能的,但我希望只用标准库就可以做到。 –

+0

添加了只有正则表达式的版本,而不必添加熊猫 – SerialDev