【问题标题】:Extracting all JavaScript filenames from a log file using Python3使用 Python3 从日志文件中提取所有 JavaScript 文件名
【发布时间】:2020-03-14 05:07:50
【问题描述】:

我是 Python3 的新手并使用文本文件。我正在尝试从以 JavaScript (.js) 扩展名结尾的日志文件中提取所有文件名。该文件还包含其他文件扩展名。我只想返回文件名而不是路径,按字母顺序对输出进行排序并显示 uniuqe 值,因为日志条目中有重复。

日志文件中的示例是:

72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/jquery.js HTTP/1.1" 200 25139

22.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/jquery.jshowoff.js HTTP/1.1" 200 25139

在这种情况下,我只想返回 jquery.jsjquery.jshowoff.js 而不是 HTTP 请求和其他日志数据。

这是我目前的代码:

filepath = '/home/user/Documents/access_log.txt'
with open(filepath, 'r') as access_log:
    contents = access_log.readlines()
    for line in contents:
        if ".js" in line:
            print(line)

我的输出只返回包含 .js 的行,但我不知道如何提取其余部分。我曾尝试使用正则表达式进行匹配,但没有成功,因为我也是新手。任何帮助将不胜感激。

【问题讨论】:

    标签: python-3.x text-extraction


    【解决方案1】:

    这是另一个纯 Python 解决方案,使用以下 logfile.txt 作为我的输入:

    72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/jquery.js HTTP/1.1" 200 25139
    22.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/jquery.jshowoff.js HTTP/1.1" 200 25139
    72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /2468.js HTTP/1.1" 200 25139
    72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /Abcd.js HTTP/1.1" 200 25139
    22.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /abcd.js HTTP/1.1" 200 25139
    72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /aBcd.js HTTP/1.1" 200 25139
    22.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET / asd.js HTTP/1.1" 200 25139
    72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/index.html HTTP/1.1" 200 25139
    72.133.47.242 - - [25/Apr/2013:15:45:28 -0700] "GET /include/login.jsp HTTP/1.1" 200 25139
    

    所有 JavaScript 文件名都存储在 set 中,因为您只需要唯一值。在打印之前,它们按字母顺序排序。

    它遍历每一行,从字符串的末尾开始找到第一个.js的索引,然后从找到.js的位置开始找到第一个/的索引,朝向离开了。

    使用这两个索引对行进行切片以提供文件名。如果找不到.jsrfind 将返回-1,这无关紧要,因为我们会在最后检查文件名是否以.js 结尾,然后再将其添加到set。您可以使用rindex,但对于没有.js 的行,您需要处理ValueError

    filenames = set()
    
    with open(r"C:\Users\Old Joe\Desktop\logfile.txt") as f:
        for line in f:
            end = line.rfind(".js") + 3 # 3 = len(".js")
            start = line.rfind("/", 0, end) + 1 # 1 = len("/")
            filename = line[start:end]
            if filename.endswith(".js"):
                filenames.add(filename)
    
    
    for filename in sorted(filenames, key=str.lower):
        print(filename)
    

    输出:

     asd.js
    2468.js
    aBcd.js
    abcd.js
    Abcd.js
    jquery.js
    jquery.jshowoff.js
    login.js
    

    【讨论】:

      【解决方案2】:

      这可以用正则表达式来完成,但我想我只提供一个 python 解决方案。

      我采用的方法是根据操作系统路径字符分割每一行:/。对于 Windows 操作系统,这将是 '\'(如果您希望它是跨平台的,请记住这一点)。这给出了一个列表。然后我们在列表中的每个元素中搜索“.js”。空间应该一直存在。具有文件名的元素将在文件名之后有额外的东西,所以只需在“.js”上拆分,并且只保留该拆分的第一个元素。我也在代码中注释了这些片段。

      with open(filepath, 'r') as access_log:
          contents = access_log.readlines()
          log_filenames = []
          for line in contents:
              # log_filenames on mac/linux will use / so split on that then search for filename
              for fragment in line.split('/'):
                  if ".js " in fragment:
                      # there will be text after .js, so remove it
                      frags = fragment.split('.js ')
                      # split on ".js " will give us the base filename as first element of list
                      basename = frags[0]
                      filename = basename + '.js'
                      log_filenames.append(filename)
          # get unique values
          log_filenames = list(set(log_filenames))
          # sort
          log_filenames.sort()
          print('\n'.join(log_filenames))
      

      输出:

      jquery.js
      jquery.jshowoff.js
      

      注意:在获取唯一值时,我将set 转换回list,以防您不习惯使用sets。

      【讨论】:

      • @Sturat 谢谢你的帮助。我稍微调整了您的代码,因为您的 sn-p 仅输出 jquery.js,但还有其他文件更长一些,其中也包含 jquery.js。在 frags = fragment.split('.js ') 中,我删除了 .js 并将其留作空格。然后返回没有 .js 的基本名称,输出看起来就是我所追求的。现在我需要对输出进行排序,以免返回重复项。
      • @Atreyu 我忘了没有重复和排序。我修好了。但是,代码对我有用。如果您复制并粘贴它,请尝试输入它(主要是 .split('.js ')。如果它只返回 jquery.js,那么这意味着 `.split('.js') 中没有空格。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多