정보마당

파이썬 parse_qsl 사용법과 원리및 구조 파악 하기

IT(Idea Technology) 흑기사 2024. 11. 22. 19:37

파이썬의 parse_qsl 함수는 URL 쿼리 문자열을 파싱하여 키-값 쌍의 리스트로 반환하는 유용한 도구입니다. 이 함수는 urllib.parse 모듈에서 제공되는데 파이썬의 장점의 깔끔한 코딩을 할 수 있도록 도와주는 함수입니다. 근데 만일 이걸 사용안하고 코딩을 한다면 어떻게 될까요? 어떤 원리로  parse_qsl은 작동하는지 알아보도록 하겠습니다.

파이썬 parse_qsl 사용법과 원리및 구조

 

먼저 예를 하나 보여드리겠습니다. url을 보면 GET방식으로 데이터를 호출하면 Query String값이 bbsno=30&no=310과 같이 문자열 형태로 이루어져 있어서  urllib.parse에는 query string을 파싱해서 collection으로 반환해주는 parse_qs와 parse_qsl 함수가 있습니다.

 

from urllib.parse import urlparse, parse_qs, parse_qsl

link="https://mydomain.com?bbsno=30&no=310&sort=name"

url_params = urlparse(link)

print(parse_qs(url_params.query)) 
# {'bbsno': ['30'], 'no': ['310'], 'sort': ['name']}
print(parse_qsl(url_params.query))
#[('bbsno', '30'), ('no', '310'), ('sort', 'name')]

# parse_qs 요소 분리
qs1 = dict(parse_qs(url_params.query))
# parse_qs의 결과를 dictionary로 캐스팅
bbsno1=qs1['bbsno'] 
no1=qs1['no'] 
#value값이 리스타로 들어옴
print("bbsno1:"+bbsno1[0]+",no1:"+no1[0]) #bbsno1:30,no1:310

# parse_qsl 요소 분리
qs = dict(parse_qsl(url_params.query))
# parse_qsl의 결과를 dictionary로 캐스팅
bbsno=qs['bbsno'] 
no=qs['no'] 
print("bbsno:"+bbsno+",no:"+no) #bbsno:30,no:310

 

위와같이 결과를 얻을 수 있는데 먼저 parse_qs와 parse_qsl 의 차이를 알아보도록 하겠습니다.
parse_qs는 key에 대해 value들을 list로 묶어서 dictionary로 반환합니다. 반면 parse_qsl은 key-value pair 각각을 tuple로 만들어서 list로 반환한다는 차이가 있습니다. 사용법도 살짝 다르지만 query string의 key가 표준에 의해서 중복이 허용되기 때문에 문제가 발생할 수 있습니다.

 

from urllib.parse import urlparse, parse_qs, parse_qsl

#no 값이 두개가 있는 경우
link="https://mydomain.com?bbsno=30&no=310&sort=name&no=900"

url_params = urlparse(link)

print(parse_qs(url_params.query))
#{'bbsno': ['30'], 'no': ['310', '900'], 'sort': ['name']}
print(parse_qsl(url_params.query)) 
#[('bbsno', '30'), ('no', '310'), ('sort', 'name'), ('no', '900')]

# parse_qs 요소 분리
qs1 = dict(parse_qs(url_params.query))
# parse_qs의 결과를 dictionary로 캐스팅
bbsno1=qs1['bbsno'] 
no1=qs1['no'] 
#value값이 리스타로 들어옴
print("bbsno1:"+bbsno1[0]+",no1:"+no1[0]) #bbsno1:30,no1:310

# parse_qsl 요소 분리
qs = dict(parse_qsl(url_params.query))
# parse_qsl의 결과를 dictionary로 캐스팅
bbsno=qs['bbsno'] 
no=qs['no'] 
print("bbsno:"+bbsno+",no:"+no) #bbsno:30,no:900

 

query string을 보면 no 값이 310과 900이렇게 두개가 있습니다. 이럴때 쿼리 param이 중복되었을때는 제일 나중에 온 값으로 서버에서는 인식하기 때문에 900이 정상입니다. 하지만 parse_qs를 사용하면 리스트의 첫번째 값인 310을 조회하고 parse_qsl를 사용하면 정상적으로 900이 찍히는것을 볼 수 있습니다. 왜냐면 parse_qsl은 중복 키를 허용하며, 동일 키의 모든 값을 반환하기 때문입니다.

중복 데이터

 

아주 간단하게 깔끔하게 정리된것을 볼 수 있습다. 그렇다면 어떤 원리고 이렇게 처리가 가능한것일까요?

간단하게 parse_qsl을 사용하지 않고 주어진 URL에서 쿼리 문자열을 직접 파싱하는 것입니다. URL에서 쿼리 문자열을 추출하고 &와 =로 나누어 키-값 쌍을 처리해서 결과값을 가져오면 됩니다. 다음 소스를 보시겠습니다.

from urllib.parse import urlparse, parse_qs, parse_qsl

def user_query_parser(url):
    # '?'를 기준으로 쿼리 문자열 추출
    if '?' in url:
        query_string = url.split('?', 1)[1]  # '?' 이후의 문자열
    else:
        query_string = ''

    # 결과를 담을 리스트
    parsed_result = []

    # '&'로 분리하여 키-값 쌍 나누기
    pairs = query_string.split('&')
    for pair in pairs:
        if '=' in pair:
            key, value = pair.split('=', 1)  # '='로 분리
        else:
            key, value = pair, ''  # 값이 없는 경우 빈 문자열 처리

        # URL 디코딩
        key = decode_url(key)
        value = decode_url(value)

        # 결과 추가
        parsed_result.append((key, value))

    return parsed_result


def decode_url(value):
    """URL 디코딩: %xx 형식을 변환"""
    import urllib.parse
    return urllib.parse.unquote(value)

link="https://mydomain.com?bbsno=30&no=310&sort=name&no=900"
parts = urlparse(link)

print(parse_qsl(parts.query)) # [('sort', 'name'), ('keyword', 'planb')]

parts = urlparse(link)
# 요소 분리
qs = dict(parse_qsl(parts.query))
# parse_qsl의 결과를 dictionary로 캐스팅
bbsno=qs['bbsno'] 
no=qs['no'] 

print("bbsno:"+bbsno+",no:"+no) #bbsno:30,no:900


print("#############################")


parsed_result1 = user_query_parser(link)
print(parsed_result1)
bbsno_next=qs['bbsno'] 
no_next=qs['no'] 
print("bbsno_next:"+bbsno_next+",no_next:"+no_next) #bbsno_next:30,no_next:900

 

결과는 아래와 같이 동일한 데이터임을 확인할 수 있습니다.

최종결과

 

단순하게 url을 split을 잘 사용해서 데이터를 리스트로 변환해서 가져오면 됩니다.  파이썬의 장점을 저는 깔끔한 코딩과 개발자가 고민해야 할 부분을 거의 모든것을 함수화 시켰다는것이라 봅니다. 파이썬으로 개발자의 능력치를 키워보세요

 

 

같이보면 좋은 글

 

 

파이썬으로 xml 데이터 날짜로 소팅하는 방법

파이썬으로 xml 데이터를 처리하다보면 정렬을 좀 하고 싶다라는 생각이 들 수 있습니다. 전 xml 데이터를 조회후 업무상 날짜별로 해서 데이터를 가져와야 한적이 있는데 처음에는 루프로 돌릴

kcy0142.tistory.com