使用python和re.findall,I';我试图计算apache日志中有效的域命中数
这是我的日志文件中“有效”行的一个示例:使用python和re.findall,I';我试图计算apache日志中有效的域命中数,python,regex,apache,findall,logfile,Python,Regex,Apache,Findall,Logfile,这是我的日志文件中“有效”行的一个示例: 194.81.31.125---[129/Dec/2013:22:03:09-0500]“获取http://www.firemaiden.hu/cgi-bin/top/topsites.cgi?an12 HTTP/1.0“200 558”http://Afrique“Mozilla/4.0(兼容;MSIE 5.5;Windows 98)” 我得到了这个re.findall表达式:(GET | POST)\s(http://https/)[a-zA-Z]+
194.81.31.125---[129/Dec/2013:22:03:09-0500]“获取http://www.firemaiden.hu/cgi-bin/top/topsites.cgi?an12 HTTP/1.0“200 558”http://Afrique“Mozilla/4.0(兼容;MSIE 5.5;Windows 98)”
我得到了这个re.findall表达式:(GET | POST)\s(http://https/)[a-zA-Z]+.+?“\s200
此表达式包含有效行的所有规则,但不提取域
我想对每个日期的顶级域(本例中为“hu”)进行计数,并将每个域的计数转储到一个有组织的日志文件中。我还想将无效行提取到另一个日志文件中
理想情况下,输出为:
2013年12月12日[tab]as:1[tab]ab:2[tab]hu:4
2013年12月13日[tab]as:4[tab]br:7[tab]cd:8
当然,它不会提取域;您没有通过将域括在括号中将其放入捕获组
因此,首先要做的是添加括号:
r'(GET|POST)\s(http://|https//)([a-zA-Z]+.+?)"\s200'
但这仍然是不对的,因为它将捕获整个www.firemaiden.hu/cgi-bin/top/topsites.cgi?an12 HTTP/1.0
,而不仅仅是www.firemaiden.hu
。这是因为你只有一组字母,后面跟的是引号内的任何东西。你只需要字母和点(对于DNS来说,这实际上并不正确,但让我们暂时忽略它)。如下所示:
r'(GET|POST)\s(http://|https//)([a-zA-Z\.]+).+?"\s200'
现在你可以看到www.firemaiden.hu
但是你想要的只是.hu
,对吗?那么,你真正需要的是尽可能多的字母和点,直到一个点后面的一组字母:
r'(GET|POST)\s(http://|https//)[a-zA-Z\.]+\.([a-zA-Z]+).+?"\s200'
但是,理论上,您需要阅读每个根服务器的DNS名称规则。但是标准世界根下的任何内容都遵循LDH规则:字母、数字、连字符。因此,您需要[a-zA-Z0-9-\.]
,对吗
但许多服务器也会接受下划线并将其视为连字符,有些服务器会将()名称解码为Unicode以进行日志记录,因此即使这样也可能不对
综上所述,我认为,与其使用您不知道如何编写并且可能不理解的regexp,不如使用更简单的regexp来获取URL(您已经知道如何做),然后使用专用的URL解析器来破解它:
r'(GET|POST)\s(\S+)\s.*?200'
然后:
现在
p.scheme
是您的'http'
或'https'
,p.netloc
是'www.firemaiden.hu'
(您可以很容易地称之为.split('.')[-1]
)等。感谢您提供的信息……我很好奇如何解决域服务器仅位于一个“.”之后的情况。例如:http://firemaiden.com
@kegewe:你说的“如何解决这种情况”是什么意思"?你试过我的任何一个例子吗?这两个例子都为你提供了该URL的com
。这不是你想要的吗?对不起,我没有使用urllib,而是尝试了你建议的对正则表达式的第一次修改,我能够将域作为元组输出的第三个元素。现在我只需要组织输出。@kegewe:哪一个?如答案中所述,前两个根本不起作用。第三个,为www.firemaiden.hu
工作的,也为firemaiden.com
工作。那么,你有什么问题吗?似乎第三个也返回了一些非顶级域的值。例如,它返回了一个类似“sou”的词地址:www.southern-charms.com
p = urllib.parse.urlparse(match[1])