지구정복
[Python] pandas 사용하기 (웹서버 로그 분석) 본문
출처: 빅데이터를 지탱하는 기술
책에 나와있는 코드가 실행이 안되서 제가 약간 수정을 했습니다~
책에 나온 예제 데이터는 더 이상 다운로드할 수 없길래 비슷한 웹서버 로그를 찾아서 진행했다.
아래에서 다운로드 받을 수 있다.
*운영환경
윈도우10
파이썬3.8.5
IDE: 이클립스pydev
1. 로그 데이터 파싱하기
해당 로그 데이터에서 필요한 부분만 정규표현식을 이용해서 추출하고 이를 pandas를 이용해서 데이터프레임 형식으로 만들어본다.
import re
import pandas as pd
import os.path
#로그 데이터를 확인하고 추출하고 싶은 데이터만 정규표현식을 이용해서 추출
#시간, 웹서버요청정보, 요청결과, 크기
pattern = re.compile( '^\S+ \S+ \S+ \[(.*)\] "(.*)" (\S+) (\S+) ".*"$')
def parse_access_log( path ):
for line in open( path ):
for m in pattern.finditer( line ):
yield m.groups()
#데이터프레임 만들기
columns = [ 'time', 'request', 'status', 'bytes' ]
df = pd.DataFrame( parse_access_log( 'access.log' ), columns=columns )
#print( df )
#시간을 보기쉽게 형식 변경
df.time = pd.to_datetime( df.time, format='%d/%b/%Y:%X', exact=False )
print( df.head( 5 ) )
#데이터프레임을 csv파일로 저장
file = '.\\access_log.csv'
if os.path.isfile( file ):
os.remove( file )
df.to_csv( 'access_log.csv', index=False )
위와 같이 파싱이 되었고 csv파일로 저장한다.
2. 시계열 데이터 집계하기
5월17일부터 5월 19일까지 하루마다 총 몇 개의 데이터가 있는 지를 집계해본다.
import pandas as pd
#파일 불러오기, 날짜를 datetime형식으로 가져온다.
df1 = pd.read_csv( 'access_log.csv', parse_dates=['time'] )
#시간을 인덱스로 지정한다.
df2 = df1.set_index( 'time' )
#인덱스에 의한 시간을 필터링한다. 2015.05.17 ~2015.05.19
df3 = df2.loc['2015-05-17':'2015-05-19']
#1일분의 액세스 수를 카운트한다.
print( df3.resample( '1d' ).size() )
혹시 numpy와 python버전이 맞지 않다는 에러가 뜨시는 분은 아래 글을 참고바랍니다.!
https://earthconquest.tistory.com/387
3. SQL을 이용해서 2와 똑같은 결과 출력하기
먼저 sql을 사용하다가 아래와 같은 에러가 뜰 수도 있다.
ImportError: DLL load failed: 지정된 모듈을 찾을 수 없습니다.
이는 인터프리터 라이브러리의 바이너리 파일들을 환경변수에 설정해주면 해결된다.
이는 다른 블로거님의 글을 참고하길 바란다. 자신의 아나콘다3 디렉터리 주소를 확인하고 환경변수로 설정하자.
나의 경우 c:/user/anaconda3/Library/bin에 있어서 이렇게 설정했다.
https://eboong.tistory.com/293
이제 sqlite3를 연결해서 db를 만들고 테이블을 만들고 데이터를 집어넣은 뒤
pandas의 read_sql()를 이용해서 db의 쿼리결과를 데이터프레임형식으로 만들어보자.
import pandas as pd
import sqlite3
#sqlite3 DB만들기
conn = sqlite3.connect( 'WebLogSQL.db' )
#sqlite3에 연결해서 테이블 만들기
cursor = conn.cursor()
cursor = conn.execute('DROP TABLE IF EXISTS access_log;')
cursor = conn.execute('CREATE TABLE IF NOT EXISTS access_log (time test, request text, status text, bytes text);')
#변수를 이용한 insert 쿼리를 만든다.
sql_insert = 'INSERT INTO access_log VALUES (?, ?, ?, ?);'
#csv파일을 불러와서 한 줄씩 쿼리를 실행해서 데이터를 insert한다.
f = open( './access_log.csv', 'r', encoding='utf-8' )
res = 0
for row in f.readlines():
line = row.split(',')
line = tuple( line )
try:
cursor.execute( sql_insert, line )
except:
continue
res += 1
print( '쿼리 입력횟수: ', res )
conn.commit()
#해당 날짜의 데이터수 조회하기
sql_select = '''
SELECT substr( time, 1, 10 ) time, count(*) count
FROM access_log
WHERE time BETWEEN '2015-05-17' AND '2015-05-20'
GROUP BY 1
ORDER BY 1;
'''
df = pd.read_sql( sql_select, conn )
print( df )
#sqlite3연결 끊기
cursor.close()
위 코드를 실행하면 아래와 같은 결과가 나오고 이는 2에서의 결과와 같은 것을 알 수 있다.
'데이터 엔지니어링 정복 > Python' 카테고리의 다른 글
[python] 파이썬3.8.5에 numpy모듈 버전 맞지 않는다고 뜰 때 (2) | 2021.08.31 |
---|---|
[Python] Linux CentOS 7에 파이썬3.9버전 설치하기 (3) | 2021.05.31 |
[Python] 리눅스CentOS 7에서 파이썬으로 웹 크롤링하기 4 (selenium - 네이버 로그인하기) (0) | 2021.05.17 |
[Python] 리눅스CentOS 7에서 파이썬으로 웹 크롤링하기 3 (selenium - 트위치 영상 다운로드하기) (0) | 2021.05.17 |
[Python] 리눅스CentOS 7에서 파이썬으로 웹 크롤링하기 2 (selenium- css태그) (0) | 2021.05.17 |