简体   繁体   English

使用boto3解析AWS S3中的文件

[英]Parse files in AWS S3 with boto3

I am attempting to read files from my S3 bucket, and parse them with a regex pattern. 我正在尝试从S3存储桶中读取文件,并使用正则表达式模式对其进行解析。 However, I have not been able to figure out to read the files line by line. 但是,我无法找出逐行读取文件的方法。 Is there a way to do this or a different way I need to be approaching this for parsing? 有没有办法做到这一点,或者我需要采用其他方式来进行解析?

pattern = '^(19|20)\d\d[-.](0[1-9]|1[012])[-.](0[1-9]|[12][0-9]|3[01])[ \t]+([0-9]|0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9][ \t]+(?:[0-9]{1,3}\.){3}[0-9]{1,3}[ \t]+(?:GET|POST|PUT)[ \t]+([^\s]+)[ \t]+[1-5][0-9][0-9][ \t]+(\d+)[ \t]+(\d+)[ \t]+"(?:[^"\\]|\\.)*"[ \t]+"(?:[^"\\]|\\.)*"[ \t]+"(?:[^"\\]|\\.)*"'

s3 = session.resource('s3')
bucket_name = s3.Bucket(bucket)
data = [obj for obj in list(bucket_name.objects.filter(Prefix=prefix)) if obj.key != prefix]

for obj in data:
    key = obj.key
    body = obj.get()['Body'].read()
    print(key)
    print(body)
    for line in body:
        print(line)

So I am able to see the correct file and able to read the whole body of the file (close to an IIS log). 因此,我能够看到正确的文件并能够读取文件的整个正文(接近IIS日志)。 However when I try to iterate the lines, I get numbers. 但是,当我尝试迭代行时,会得到数字。 So the output of print(line) is 所以print(line)的输出是

35
101
119
147
etc.

I have no idea where these numbers are coming from. 我不知道这些数字是从哪里来的。 Are they words, characters, something else? 他们是单词,字符还是其他东西吗?

My goal is to apply my pattern once I am able to read the file line by line with the regular expression operator. 我的目标是一旦我能够使用正则表达式运算符逐行读取文件,就应用我的模式。

EDIT: Here is one of my log lines 编辑:这是我的日志行之一

2016-06-14  14:03:42    1.1.1.1 GET /origin/ScriptResource.axd?=5f9d5645    200 26222   0   "site.com/en-US/CategoryPage.aspx"  "Mozilla/5.0 (Linux; Android 4.4.4; SM-G318HZ Build/KTU84P)"    "ASP.NET_SessionId=emfyTVRJNqgijw=; __SessionCookie=bQMfQzEtcnfMSQ==; __CSARedirectTags=ABOcOxWK/O5Rw==; dtCookie=B52435A514751459148783108ADF35D5|VVMrZVN1aXRlK1BXU3wx"

Text file with below content I have used in below solution: 我在以下解决方案中使用了以下内容的文本文件:

I love AWS.
I love boto3.
I love boto2.

I think the problem is with line : 我认为问题出在line:

for line in body:

It iterates character by character instead of line by line. 逐字符而不是逐行迭代。

C:\Users\Administrator\Desktop>python bt.py
I

l
o
v
e

A
W
S
.



I

l
o
v
e

b
o
t
o
3
.



I

l
o
v
e

b
o
t
o
2
.

C:\Users\Administrator\Desktop>

Instead we use as below : 相反,我们使用以下方法:

for line in body.splitlines():

then the output looks like this 然后输出看起来像这样

C:\Users\Administrator\Desktop>python bt.py
I love AWS.
I love boto3.
I love boto2.

C:\Users\Administrator\Desktop>

Applying above things, I tried the below code on text file with small regex which will give boto versions from the file. 应用以上内容,我在文本文件上尝试了以下带有小正则表达式的代码,该代码将提供文件的boto版本。

import re
header = ['Date', 'time', 'IP', 'method', 'request', 'status code', 'bytes', 'time taken', 'referrer', 'user agent', 'cookie']
s3 = session.resource('s3')
bucket_name = s3.Bucket(bucket)
data = [obj for obj in list(bucket_name.objects.filter(Prefix=prefix)) if obj.key != prefix]

for obj in data:
    key = obj.key
    body = obj.get()['Body'].read()
    #print(key)
    #print(body)
    x=0
    for line in body:
        m = re.search(r'(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})\s+([\d\.]+)\s+([GET|PUT|POST]+)\s+([\S]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+([\S]+)\s+(\".*?\")\s+(.*)',line)
        if m is not None:
            for i in range(11):
                print header[i]," - ",m.group(x)
                x+=1
        print "------------------------------------"  
        x=0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM