为了账号安全,请及时绑定邮箱和手机立即绑定

Python解析网络访问日志

Python解析网络访问日志

慕桂英3389331 2022-01-05 12:14:40
我正在尝试从访问日志中解析特定数据,日志格式各不相同,可能来自 nginx 或 apache。我需要获取以下数据:远程主机IP请求日期时间请求类型 {GET|POST|PUT|..etc}请求路径 {/main/index.html 等}HTTP 版本 {HTTP 1.1 | HTTP 1.0}HTTP 响应代码 {200|400|403 ...etc}我尝试使用 split 但它并不总是有效,因为日志格式并不总是相同:sample = """::1 - - [03/Jan/2018:21:28:49 +0100] "GET /moodle/course/view.php?id=19 HTTP/1.1" 200 78325 "http://localhost/moodle/login/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"83.198.250.175 - - [22/Mar/2009:07:40:06 +0100] "GET /style.css HTTP/1.1" 200 1692 "http://www.example.org/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Wanadoo 6.7; Orange 8.0)" "-"212.31.110.34 0.597 - [16/May/2018:12:30:44 +0000] safefin.example.com "GET / HTTP/1.1" 200 18193 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36"151.227.152.48 - - [02/Jul/2014:14:35:55 +0100] "GET /css/main.css HTTP/1.1" 200 4658 "http://example.org/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"109.169.248.247 - - [12/Dec/2015:18:25:11 +0100] "POST /administrator/index.php HTTP/1.1" 200 4494 "http://example.net/administrator/" "Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0" "-"80.91.33.133 - - [17/May/2015:08:05:24 +0000] "GET /downloads/product_1 HTTP/1.1" 304 0 "-" "Debian APT-HTTP/1.3 (0.8.16~exp12ubuntu10.17)"217.168.17.5 - - [17/May/2015:08:05:34 +0000] "GET /downloads/product_1 HTTP/1.1" 200 490 "-" "Debian APT-HTTP/1.3 (0.8.10.3)"
查看完整描述

2 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

如果您想使用正则表达式来解析日志,这里有一些可能会有所帮助:


捕获 IP 地址有点困难。如果你想检查它是一个有效的 IP 地址,试试这个。否则,如果您想要 4 组最多 3 位数字并用点分隔的数字:


\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}

对于日期时间,您似乎可以获取第一次出现的用方括号括起来的字符


\[([^\]]+)\]

对于方法、路径和响应,看起来您可以抓取第一次出现的用引号括起来的字符,然后直接抓取后面的数字


"([^"]+)"\s+(\d{1,3})

因为这里有多个匹配项,所以您可以使用组来抓取单个部分。使用此正则表达式,您将选取第一组并简单地去掉“GET、POST、DELETE 等”,剩下的就是路径。


使用 python 的re库并将每个正则表达式应用到输入中的一行,看看你得到了什么


#!/usr/bin/env python

import re


bad_ip_regex = re.compile("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")

datetime_regex = re.compile("\[([^\]]+)\]")

other_regex = re.compile('"([^"]+)"\s+(\d{1,3})')

with open("input.log", "r") as f:

  for line in f:

    item = {}


    # attempt to grab IP

    ip = bad_ip_regex.search(line)

    if ip:

      item["remote_host"] = ip.group(0)

    else:

      # no ip, just skip?

      continue


    # attempt to grab datetime

    datetime = datetime_regex.search(line)

    if datetime:

      item["datetime"] = datetime.group(1)

    else:

      continue


    # attempt to grab other

    other = other_regex.search(line)

    if other:

      item["method"] = other.group(1).split()[0]

      item["path"] = other.group(1).split()[1]

      item["response"] = other.group(2)

    else:

      continue


    print(item)

因为您无法保证这些项目的顺序,所以尝试使用正则表达式一次获取所有字段是没有意义的。只需在每一行上一次尝试一个。


查看完整回答
反对 回复 2022-01-05
?
料青山看我应如是

TA贡献1772条经验 获得超8个赞

嗯...你的指示有点误导,但幸运的是,我不久前做过这样的事情,所以我只是改编了一些你可以使用的脏代码。请记住,在 Python 字典中,默认情况下不会以任何特定顺序显示。


但是下面的代码应该可以完成您的需要并使用单个正则表达式


>>> sample = '''

::1 - - [03/Jan/2018:21:28:49 +0100] "GET /moodle/course/view.php?id=19 HTTP/1.1" 200 78325 "http://localhost/moodle/login/index.php" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"

83.198.250.175 - - [22/Mar/2009:07:40:06 +0100] "GET /style.css HTTP/1.1" 200 1692 "http://www.example.org/" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Wanadoo 6.7; Orange 8.0)" "-"

212.31.110.34 0.597 - [16/May/2018:12:30:44 +0000] safefin.example.com "GET / HTTP/1.1" 200 18193 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36"

151.227.152.48 - - [02/Jul/2014:14:35:55 +0100] "GET /css/main.css HTTP/1.1" 200 4658 "http://example.org/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"

109.169.248.247 - - [12/Dec/2015:18:25:11 +0100] "POST /administrator/index.php HTTP/1.1" 200 4494 "http://example.net/administrator/" "Mozilla/5.0 (Windows NT 6.0; rv:34.0) Gecko/20100101 Firefox/34.0" "-"

80.91.33.133 - - [17/May/2015:08:05:24 +0000] "GET /downloads/product_1 HTTP/1.1" 304 0 "-" "Debian APT-HTTP/1.3 (0.8.16~exp12ubuntu10.17)"

217.168.17.5 - - [17/May/2015:08:05:34 +0000] "GET /downloads/product_1 HTTP/1.1" 200 490 "-" "Debian APT-HTTP/1.3 (0.8.10.3)"

192.168.0.11 - - [27/Jun/2016:18:36:14 -0500] "GET / HTTP/1.1" 302 - "-" "Mozilla/5.0 (Linux; Android 5.1.1; SM-N910T Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.81 Mobile Safari/537.36"

51.68.152.26 - - [09/Apr/2019:01:37:30 +0400] "GET / HTTP/1.1" 302 0 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

71.169.154.24 - - [01/Mar/2015:20:58:55 -0500] "GET /BarHarborcemeteries/Burns-RichardsonCemeteryimages/general%20view%20(2008).jpg HTTP/1.1" 200 165457 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.3.18 (KHTML, like Gecko) Version/7.1.3 Safari/537.85.12"

94.90.115.82 - - [02/Apr/2012:04:56:17 +0900] "GET /manager/html HTTP/1.1" 404 77 "-" "Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/5.0"

172.20.32.1 - - [25/Feb/2015:10:42:29 +0300] "PUT /putfile?partNumber=5&uploadId=2/fFEtO5aTFYNO7tjxbbmw6QkGOmeeOFt HTTP/1.1" 200 - "-" "-"

172.20.32.1 - - [25/Feb/2015:10:42:32 +0300] "POST /putfile?uploadId=2/fFEtO5aTFYNO7tjxbbmw6QkGOmeeOFt HTTP/1.1" 200 279 "-" "-"

172.20.32.1 - - [25/Feb/2015:10:43:04 +0300] "DELETE /putfile HTTP/1.1" 400 81 "-" "-"

172.20.32.1 - - [25/Feb/2015:10:43:04 +0300] "DELETE /putfile HTTP/1.1" 204 - "-" "-"

172.20.32.1 - - [25/Feb/2015:10:41:02 +0300] "POST /putfile?uploads HTTP/1.1" 200 242 "-" "-"

151.227.152.48 - - [02/Jul/2014:14:35:56 +0100] "GET /img/Customers/Absolute-Steel-Framing.gif HTTP/1.1" 200 10123 "http://example.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36"

159.226.202.17 - - [31/Aug/2010:23:45:30 +0100] "GET / HTTP/1.1" 403 323 "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; iCafeMedia; .NET CLR 2.0.50727; CIBA)"

65.55.3.169 - - [01/Sep/2010:08:03:47 +0100] "GET /robots.txt HTTP/1.1" 403 272 "-" "msnbot/2.0b (+http://search.example.com/msnbot.htm)._"

66.187.104.20 - - [24/Apr/2009:19:15:52 +1100] "GET /misc/arrow-desc.png HTTP/1.1" 404 217

77.35.168.108 - - [28/Apr/2009:10:38:09 +1100] "GET / HTTP/1.1" 200 85

77.35.172.105 - - [28/Apr/2009:12:49:27 +1100] "GET / HTTP/1.1" 304 -

79.137.201.45 - - [02/May/2009:12:17:26 +1100] "GET /robots.txt HTTP/1.0" 404 208

151.21.4.47 - - [17/Feb/2018:16:06:48 +0100] "GET /noindex/css/open-sans.css HTTP/1.1" 200 5081 "http://94.177.222.96/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0"

151.21.4.47 - - [17/Feb/2018:16:06:48 +0100] "GET /images/apache_pb.gif HTTP/1.1" 200 2326 "http://94.177.222.96/" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0"'''





>>> def text_to_dict(string):

        import re

        dict_array = []

        found_items = re.findall('(?m)^((?:[\d]{1,3}\.){3}[\d]{1,3}|[\d]*[:]*[\d]*)[\S\ ]*?\[([\S\ ]*?)\][\S\ ]*?\"([A-Z]+)[\S\ ]*?(/(?=[\s]+)|/[\s]*[\S]+)[\S\ ]*?(HTTP[\S]*?)\"[\S\ ]*?([\d]{3}(?=\s|$))', string)

        for i in range(len(found_items)):

            try:

                dict = {"remote_host":found_items[i][0], "datetime":found_items[i][1], "method":found_items[i][2], "path":found_items[i][3],"http_version":found_items[i][4], "response_code":found_items[i][5]}

                dict_array.append(dict)

            except:

                print('\n\n================Failed')

                print(found_items[i])

        return dict_array





>>> found_items = text_to_dict(sample)




>>> for elements in found_items:

        print(elements)






 #OUTPUT

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '03/Jan/2018:21:28:49 +0100', 'path': '/moodle/course/view.php?id=19', 'remote_host': '::1', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '22/Mar/2009:07:40:06 +0100', 'path': '/style.css', 'remote_host': '83.198.250.175', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '16/May/2018:12:30:44 +0000', 'path': '/', 'remote_host': '212.31.110.34', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '02/Jul/2014:14:35:55 +0100', 'path': '/css/main.css', 'remote_host': '151.227.152.48', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '12/Dec/2015:18:25:11 +0100', 'path': '/administrator/index.php', 'remote_host': '109.169.248.247', 'method': 'POST'}

 {'http_version': 'HTTP/1.1', 'response_code': '304', 'datetime': '17/May/2015:08:05:24 +0000', 'path': '/downloads/product_1', 'remote_host': '80.91.33.133', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '17/May/2015:08:05:34 +0000', 'path': '/downloads/product_1', 'remote_host': '217.168.17.5', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '302', 'datetime': '27/Jun/2016:18:36:14 -0500', 'path': '/', 'remote_host': '192.168.0.11', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '302', 'datetime': '09/Apr/2019:01:37:30 +0400', 'path': '/', 'remote_host': '51.68.152.26', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '01/Mar/2015:20:58:55 -0500', 'path': '/BarHarborcemeteries/Burns-RichardsonCemeteryimages/general%20view%20(2008).jpg', 'remote_host': '71.169.154.24', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '404', 'datetime': '02/Apr/2012:04:56:17 +0900', 'path': '/manager/html', 'remote_host': '94.90.115.82', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '25/Feb/2015:10:42:29 +0300', 'path': '/putfile?partNumber=5&uploadId=2/fFEtO5aTFYNO7tjxbbmw6QkGOmeeOFt', 'remote_host': '172.20.32.1', 'method': 'PUT'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '25/Feb/2015:10:42:32 +0300', 'path': '/putfile?uploadId=2/fFEtO5aTFYNO7tjxbbmw6QkGOmeeOFt', 'remote_host': '172.20.32.1', 'method': 'POST'}

 {'http_version': 'HTTP/1.1', 'response_code': '400', 'datetime': '25/Feb/2015:10:43:04 +0300', 'path': '/putfile', 'remote_host': '172.20.32.1', 'method': 'DELETE'}

 {'http_version': 'HTTP/1.1', 'response_code': '204', 'datetime': '25/Feb/2015:10:43:04 +0300', 'path': '/putfile', 'remote_host': '172.20.32.1', 'method': 'DELETE'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '25/Feb/2015:10:41:02 +0300', 'path': '/putfile?uploads', 'remote_host': '172.20.32.1', 'method': 'POST'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '02/Jul/2014:14:35:56 +0100', 'path': '/img/Customers/Absolute-Steel-Framing.gif', 'remote_host': '151.227.152.48', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '403', 'datetime': '31/Aug/2010:23:45:30 +0100', 'path': '/', 'remote_host': '159.226.202.17', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '403', 'datetime': '01/Sep/2010:08:03:47 +0100', 'path': '/robots.txt', 'remote_host': '65.55.3.169', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '404', 'datetime': '24/Apr/2009:19:15:52 +1100', 'path': '/misc/arrow-desc.png', 'remote_host': '66.187.104.20', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '28/Apr/2009:10:38:09 +1100', 'path': '/', 'remote_host': '77.35.168.108', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '304', 'datetime': '28/Apr/2009:12:49:27 +1100', 'path': '/', 'remote_host': '77.35.172.105', 'method': 'GET'}

 {'http_version': 'HTTP/1.0', 'response_code': '404', 'datetime': '02/May/2009:12:17:26 +1100', 'path': '/robots.txt', 'remote_host': '79.137.201.45', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '17/Feb/2018:16:06:48 +0100', 'path': '/noindex/css/open-sans.css', 'remote_host': '151.21.4.47', 'method': 'GET'}

 {'http_version': 'HTTP/1.1', 'response_code': '200', 'datetime': '17/Feb/2018:16:06:48 +0100', 'path': '/images/apache_pb.gif', 'remote_host': '151.21.4.47', 'method': 'GET'}



查看完整回答
反对 回复 2022-01-05
  • 2 回答
  • 0 关注
  • 183 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信