Python 使用正则表达式解析日志时,不断获取'NoneType'错误
下面我举了两个日志的例子。我试图找出ip、日期、时间、方法、这部分(Python 使用正则表达式解析日志时,不断获取'NoneType'错误,python,python-2.7,parsing,logparser,Python,Python 2.7,Parsing,Logparser,下面我举了两个日志的例子。我试图找出ip、日期、时间、方法、这部分(/071300/242153 HTTP/1.1“)、响应代码(仅404/200部分),以及一组中的其他部分: 66.249.69.97---[24/Sep/2014:22:25:44+0000]“GET/071300/242153http/1.1”404514“-”Mozilla/5.0(兼容;Googlebot/2.1+http://www.google.com/bot.html)“ 及 71.19.157.174-[24/S
/071300/242153 HTTP/1.1“
)、响应代码(仅404
/200
部分),以及一组中的其他部分:
66.249.69.97---[24/Sep/2014:22:25:44+0000]“GET/071300/242153http/1.1”404514“-”Mozilla/5.0(兼容;Googlebot/2.1+http://www.google.com/bot.html)“
及
71.19.157.174-[24/Sep/2014:22:26:12+0000]“GET/error HTTP/1.1”404 505-“Mozilla/5.0(X11;Linux x86_64)AppleWebKit/537.36(KHTML,像Gecko)Chrome/37.0.2062.94 Safari/537.36”
我的函数如下所示:
def parse_logs(logs):
log_list = []
for log in logs:
p = re.compile(r'''(?P<ip_addr>\d+(\.\d+){3}) - - \[(?P<date_time>.+?)\] (?P<http_method>\".+?\") (?P<return_code>\d+) \d+ "-" (?P<client>\".+?\")''')
m = p.search(log)
log_list.append([m.group('ip_addr'), m.group('date_time'), m.group('http_method'), m.group('return_code'), m.group('client')])
rdd_prepped = parse_logs(rdd.take(5))
def解析日志(日志):
日志列表=[]
对于登录日志:
p=重新编译(r''(?p\d+(\.\d+){3})-\[(?p.+?)\](?p\“+?\”)(?p\d+)\d+“-”(?p\“+?”)”)
m=p.search(日志)
日志列表.append([m.group('ip地址')、m.group('date\u time')、m.group('http\u方法')、m.group('return\u code')、m.group('client'))
rdd_prepped=parse_日志(rdd.take(5))
当我将这些日志的列表传递给函数并运行它时,我不断得到错误:
AttributeError:'NoneType'对象没有属性“collect”
当我在m=p.search(log)
下放置print(m.group('ip'))
行时,我得到错误:
AttributeError:“非类型”对象没有属性“组”
为什么我总是使用非类型?顺便说一句,我使用的是Python2.7。当这篇文章第一次发布时,正则表达式如下所示:
p = re.compile(r'''(?P<ip>\d+(\.\d+){3}) - - \[(?P<date_time>.+?)\] (?P<method>\".+?\") \
(?P<response_code>\d+) \d+ "-" (?P<client>\".+?\")''')
对于复杂的正则表达式,我喜欢使用详细模式:
regex = re.compile("""
(?P<ip>\d+(?:\.\d+){3}) # four, dot-separated sets of digits
.*? # skip ahead
\[(?P<date_time>.*?)\] # date time is everything between '[ ]'
.*? # skip
"(?P<method>.*?)" # method is everything between quotes
.*? # skip
(?P<response_code>\d+) # multiple digits
.*? # skip
"-" # don't care
.*? #
"(?P<client>.*?)" # client is everything between quotes
""", re.VERBOSE)
您的正则表达式正在匹配任何内容,并且
p.search
正在从文档编辑返回None
:抱歉,忽略此评论,我没有将正则表达式正确复制并粘贴到工具中。您的正则表达式似乎与日志文件中的一行或多行不匹配,使p.search
返回None
。您有过吗ed打印出不匹配的代码?这可能会提示您出了什么问题。好的,但在复制和粘贴时,可能会有一些代码的实现细节不明显(例如,文件中可能有不匹配的尾随空行)如果m为None,则在p.search
调用后添加:print log
可能会突出显示它们。第一次发布时,regex模式被拆分为两行,第一行末尾有一个“\”。但是该模式使用三个引号。因此regex实际上需要日志中的一个“\n”。因此该模式不匹配。该模式已被编辑所以它在一条线上,而且似乎有效。
regex = re.compile("""
(?P<ip>\d+(?:\.\d+){3}) # four, dot-separated sets of digits
.*? # skip ahead
\[(?P<date_time>.*?)\] # date time is everything between '[ ]'
.*? # skip
"(?P<method>.*?)" # method is everything between quotes
.*? # skip
(?P<response_code>\d+) # multiple digits
.*? # skip
"-" # don't care
.*? #
"(?P<client>.*?)" # client is everything between quotes
""", re.VERBOSE)
def parse_logs(logs):
log_list = []
p = re.compile(...whichever regex style you like...)
for log in logs:
m = p.search(log)
if m:
log_list.append(m.group('ip_addr', 'date_time', 'http_method,
'return_code', 'client'))
else:
print(log)
rdd_prepped = parse_logs(rdd.take(5))