본문 바로가기

개발/Python & Flask

[Python] URI쿼리 인코딩여부 판별 프로그램

회사에서 일회성으로 사용한 로그파싱 프로그램.

로그에 남겨진 url 쿼리를 파싱해서 인코딩하는 협력사와 하지않는 협력사를 색출해낸다.

신기한 것은 POST 방식으로 전달하는데 뒤에 ? 를 붙여서 쿼리문을 전달하는 회사가 굉장히 많다는 것;

 

 

 

아래는 배운 점들을 정리해봤다.

 

 

퍼센트 인코딩

url 로 넘길 때 사용불가한 특수문자들이 많다.
이 때 퍼센트(%) 인코딩을 쓰게 되는데,
아래 비예약문자들을 제외한 모든 문자들을 인코딩해줘야한다.

비예약문자

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9 - _ . ~

( 위 문자들은 인코딩이 필요없다. )

예약문자

! * ' ( ) ; : @ & = + $ , / ? # [ ]

 

그 외 모든 한글 또한 인코딩이 필요하다.


정규표현식

url의 인코딩 됐는지 여부를 확인할 때 어떻게 필터링 해야할까?
정규표현식을 사용했다.
[^\w\s-_.~%=] 를 사용했다.
\w : 모든 문자와 숫자
\s : 모든 공백문자
[ ] 한 캐릭터
* 직전의 내용 0번 이상의 반복

이정도를 사용했다.

 

% 와 = 는 비예약문자가 아니지만, 인코딩된 결과물에서 %가 포함되고, & 로 쿼리를 파싱했다면 VAR=VALUE 형태이기 때문에 =가 포함된다.

정규표현식 함수 최적화 ?

졍규표현식은 배열을 일일히 맞춰서 비교할 것 같아서 매우 시간이 오래 걸릴 것으로 생각했으나
생각보다 느리진 않았다.
match() 함수와 findall() 함수를 비교해본 결과 그렇게 차이가 나진 않았다.


파이썬 최적화

로그파일만해도 62개요, 한 로그파일당 순수 문자열만해서 70MB - 90MB 사이즈였다.

순수 텍스트로 4960MB 크기이다.

 

이제까지 돌아가기만 하는 프로그램을 생각했지만,

처음으로 실전에서 최적화를 고려해야하는 경우였다.

 

. 을 사용하면 실행시간이 크게 늘어난다는 사실을 알고 있는가?
이를 반복문 전에 미리 선언해놓으면 실행시간이 매우 매우 단축된다. (대략 30% 정도 줄어든다)

a = []
for i in rage(1000000):
  a.append(i)

를 사용한다고 예를 든다면, for문 전에 a.append 를 미리 선언하는 것이다.

a = []
ap = a.append
for i in rage(1000000):
  ap(i)

로 바꾸면 10초 걸리는 것이 7초로 줄어든다.

아 물론 전부터 알고 있던 것 한가지는 set을 적극 활용하는 것이다.
list보다 훨씬훨씬 빠르다.
추가할 때도 list 는 순차적 접근을 하고 추가하는 등 번거로운 절차가 있지만 set은 그딴게 없다.

만약 set를 출력할 때 순서를 매기고 싶다면
sorted(list(myset))
를 사용하면 된다.

 

아래는 소스코드이다!

github.com/gogoonbuntu/log_classifier/

반응형