Skip to main content
 首页 » 编程设计

python之使用 Python 将 Web 日志文件作为 CSV 文件处理

2025年04月02日52linjiqin

我正在使用 Python 3 CSV 阅读器将一些网络日志文件读入命名元组中。 我无法控制日志文件结构,并且有多种类型。

分隔符是一个空格( ),问题是一些日志文件格式在时间戳中放置了一个空格,如下面的Logfile 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 ,包括方言,但似乎没有任何东西可以处理方括号。

如何自动处理这种情况?

请您参考如下方法:

这样就可以了,您需要使用正则表达式代替 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')