본문 바로가기

Python의 URL 매개변수 16진수 인코딩 및 디코딩

기술적인 이야기/기타 개발 2024. 12. 23.
반응형

가끔 URL의 GET 매개변수를 전달하기 위해 16진수 인코딩(HEX Encoding)이나 디코딩이 필요할 때가 있지만 자주 까먹는다. 그래서 글로 박제를 해보려고 한다. 참고로 파이썬에서는 이 인코딩을 인용(quote)이라고 부르는 모양이다.

인코딩

특정 문자열을 16진수로 인코딩할 때는 urllib.parse 모듈의 quote 혹은 quote_plus 함수를 사용할 수 있다.

>>> import urllib.parse
>>> urllib.parse.quote('10==2다')
'10%3D%3D2%EB%8B%A4'
>>> urllib.parse.quote_plus('10==2다')
'10%3D%3D2%EB%8B%A4'

quotequote_plus 함수는 차이는 공백(space)을 어떻게 처리하느냐는 특징으로 갈라진다. quote_plus 함수는 이름처럼 공백을 아스키(ASCII) 코드가 아니라 +로 변환한다.

>>> import urllib.parse
>>> urllib.parse.quote('test 1234')
'test%201234'
>>> urllib.parse.quote_plus('test 1234')
'test+1234'

덤으로 만약 여러 파라미터를 한 번에 조합하는 걸 원한다면 동일한 모듈의 urlencode 함수를 사용할 수 있다.

>>> import urllib.parse
>>> urllib.parse.urlencode({
...     "name": "super\\*/user",
...     "value": 100
... })
'name=super%5C%2A%2Fuser&value=100'

디코딩

개인적으로는 별로 사용하지 않지만 인코딩(quote)이 있으면 디코딩(unquote)도 있어야 할 것 같아서 정리해 본다. 디코딩도 urllib.parse라는 동일한 모듈의 unquote 혹은 unquote_plus 함수를 사용할 수 있다.

>>> import urllib.parse
>>> urllib.parse.unquote_plus('10%3D%3D2%EB%8B%A4')
'10==2다'

이번에도 _plus가 붙은 함수는 어떤 문자를 공백으로 바꿀지 차이가 있다는 것은 눈치챌 수 있을 것이다. 만약 quote_plus로 인코딩을 했다면 unquote_plus로 디코딩하면 된다는 말이다.

URL의 쿼리 문자열 전체에서 데이터를 뽑아내려면 아래와 같은 과정을 거칠 수 있는데 쿼리를 데이터로 추출할 때 두 가지 함수 중 하나를 이용할 수 있다는 점을 먼저 짚고 예제를 보자.

>>> result = urllib.parse.urlparse("https://some.host.name/index.html?name=super%5C%2A%2Fuser&value=100")
>>> urllib.parse.parse_qs(result.query)
{'name': ['super\\*/user'], 'value': ['100']}
>>> urllib.parse.parse_qsl(result.query)
[('name', 'super\\*/user'), ('value', '100')]

urllib.parse 모듈의 urlparse 함수를 통해 URL 전체를 해석하면 여기서 query 멤버를 통해 쿼리 문자열을 얻을 수 있다. 이 문자열을 먼저 짚은 대로 동일한 모듈의 parse_qs 혹은 parse_qsl의 두 가지 함수 중 하나를 골라서 값을 분리할 수 있다. 이 두 함수는 전자는 사전형(dictionary)으로 그리고 후자는 튜플 리스트 형태로 데이터를 구성하는 방법만 다를 뿐 하는 일은 비슷하니 필요한 걸로 골라서 쓰면 될 것 같다.

이 정도면 기본적인 사항은 정리되는 것 같다.

728x90
반응형

댓글