【问题标题】:Match lines from a file and parse them on Python匹配文件中的行并在 Python 上解析它们
【发布时间】:2014-09-02 06:33:04
【问题描述】:

我有这个文件有不同的行,我只想从每一行中获取一些信息(而不是全部)这里是文件外观的示例:

18:10:12.960404 IP 132.227.127.62.12017 > 134.157.0.129.53: 28192+ A? safebrowsing-cache.google.com. (47)
18:10:12.961114 IP 134.157.0.129.53 > 132.227.127.62.12017: 28192 12/4/4 CNAME safebrowsing.cache.l.google.com., A 173.194.40.102, A 173.194.40.103, A 173.194.40.104, A 173.194.40.105, A 173.194.40.110, A 173.194.40.96, A 173.194.40.97, A 173.194.40.98, A 173.194.40.99, A 173.194.40.100, A 173.194.40.101 (394)
18:13:46.206371 IP 132.227.127.62.49296 > 134.157.0.129.53: 47153+ PTR? b._dns-sd._udp.upmc.fr. (40)
18:13:46.206871 IP 134.157.0.129.53 > 132.227.127.62.49296: 47153 NXDomain* 0/1/0 (101)
18:28:57.253746 IP 132.227.127.62.54232 > 134.157.0.129.53: 52694+ TXT? time.apple.com. (32)
18:28:57.254647 IP 134.157.0.129.53 > 132.227.127.62.54232: 52694 1/8/8 TXT "ntp minpoll 9 maxpoll 12 iburst" (381)
.......
.......

它实际上是一个 DNS 请求的输出,所以我想从中提取这些元素: [时间戳]、[srcip]、[src prt]、[dst ip]、[dst prt]、[domaine(如果存在)]、[相关ips地址]

在查看网站的旧主题后,我发现 re.match() 是一种很棒且有用的方法,但是由于您看到每一行都不同,所以我有点迷茫,有些帮助会很棒,这是我到目前为止写的代码,它是正确的:

def extractDNS(filename):
    objList = []
    obj = {}

    with open(filename) as fi:
        for line in fi:
            line = line.lower().strip()

            #18:09:29.960404
            m = re.match("(\d+):(\d+):(\d+.\d+)",line)
            if m:
                obj = {}        #New object detected
                hou = int(m.group(1))
                min = int(m.group(2))
                sec = float(m.group(3))
                obj["time"] = (hou*3600)+(min*60)+sec
                objList.append(obj)

            #IP 134.157.0.129.53
            m=re.match("IP\s+(\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}).(\d+)",bb)
            if m:
                obj["dnssrcip"]     = m.group(1)
                obj["dnssrcport"]   = m.group(2)

            # > 134.157.0.129.53:       
            m = re.match("\s+>\s+(\d{1,3}\.\d{1,3}\.\d{1,3}.\d{1,3}).(\d+):",line)
            if m: 
                obj["dnsdstip"]     = m.group(1)
                obj["dnsdstport"]   = m.group(2)


    tstFile3=open("outputFile","w+")
    tstFile3.write("%s\n" %objList)
    tstFile3.close()

extractDNS(sys.argv[1])

我知道我必须在此之后做出 if else 语句,因为它们之后的内容每次都不同,我在 3 种情况下展示了我在每个 dns 输出文件中得到的一般情况,它们是:
- 一个?后跟 CNAME、确切的域和 IP 地址,
- PTR?后跟一个 NXDOmain,表示该域不存在,所以我将忽略这一行,
- TXT?后跟一个域,但它只给出单词,所以我将忽略这两个

我只想要他们的响应包含 IP 地址的请求,在这种情况下是 A?

【问题讨论】:

    标签: python regex dns


    【解决方案1】:

    正如上面 user632657 所说,没有必要关心你不关心的线路。只需对该行使用一个正则表达式,如果不匹配,则忽略该行:

    pattern = re.compile( r'(\d{2}):(\d{2}):(\d{2}\.\d+)\s+IP\s+(\d+\.\d+\.\d+\.\d+)\.(\d+)\s+>\s+(\d+\.\d+\.\d+\.\d+)\.(\d+):\s+(\d+).*?CNAME\s+([^,]+),\s+(.*?)\s+\(\d+\)' )

    这将仅匹配 CNAME 记录。您只需要在循环之外定义一次。然后,在循环内:

    try:
        hour, minute, seconds, source_ip, source_port, dst_ip, dst_port, domain, records = pattern.match( line ).groups()
    except:
        continue
    records = [ r.split() for r in records.split( ', ' ) ]
    

    这将在相关变量中提取您询问的所有字段,并将关联的 IP 解析为对(类、IP)的列表,我认为这将很有用:P

    【讨论】:

      【解决方案2】:

      如果您知道前 5 列始终存在,为什么不直接拆分行并直接处理它们(使用 datetime 作为时间戳,并手动解析 IP 地址/端口)。然后,您可以使用正则表达式仅匹配 CNAME 记录和您在该字段中感兴趣的内容。如果您不打算实际使用输出,则无需对不同的可能性进行正则表达式扫描。因此,如果它与 CNAME 表单不匹配,那么您就不会关心如何处理它。至少,听起来是这样的。

      【讨论】:

      • 是的!谢谢!这听起来是个好主意,我尝试了很多方法来处理这个问题,我现在觉得自己很愚蠢,哈哈
      • 只是一个关于时间戳的快速问题,我之前在这段代码中尝试过:time.mktime(datetime.strptime(mu.group(1), "%H:%M:%S.%f").timetuple())
        但它不起作用..你能帮我测试一下吗跨度>
      • datetime.datetime.strptime("18:10:12.960404", "%H:%M:%S.%f").timetuple() 对我来说的话。您的小组 (1) 是否会返回一些与您认为应该有所不同的东西?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-30
      • 2020-12-15
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      • 2011-03-07
      • 1970-01-01
      相关资源
      最近更新 更多