urllib.parse
와 함께한 시간은 너무나도 힘들었다. 다른 건 다 봐줄 만 한데, query string을 다루는 건 너무나도 비직관적이었다. 그렇게 찾아낸 게 yarl(Yet another URL library)였다.
$ pip install yarl
URL
클래스가 모든 작업의 시초가 된다.
from yarl import URL
print(URL('https://velog.io')) # URL('https://velog.io')
URL의 각 요소들을 쪼개는 방식은 urllib과 매우 유사하다.
from urllib.parse import urlparse
from yarl import URL
url = 'http://user:pass@example.com:8042/over/there?name=ferret#nose'
urllib_url = urlparse(url)
yarl_url = URL(url)
print(yarl_url.scheme) # 'http'
print(urllib_url.scheme) # 'http'
print(yarl_url.user) # 'user'
print(urllib_url.username) # 'user'
print(yarl_url.password) # 'pass'
print(urllib_url.password) # 'pass'
print(yarl_url.host) # 'example.com'
print(urllib_url.hostname) # 'example.com'
print(yarl_url.port) # 8042
print(urllib_url.port) # 8042
print(yarl_url.path) # '/over/there'
print(urllib_url.path) # '/over/there'
print(yarl_url.query_string) # 'name=ferret'
print(urllib_url.query) # 'name=ferret'
print(yarl_url.query) # <MultiDictProxy('name': 'ferret')>
# urllib에는 없음
print(yarl_url.fragment) # 'nose'
print(urllib_url.fragment) # 'nose'
yarl은 기본적으로 immutable을 지향한다. 따라서 모든 수정 작업은 새로운 URL 객체를 반환하게 되어 있다.
from yarl import URL
url = URL('https://velog.io/write')
print(url.with_scheme('http')) # URL('http://velog.io/write')
print(url.with_path('/recent')) # URL('https://velog.io/recent')
print(url.update_query('edit_id=abcde')) # URL('https://velog.io/write?edit_id=abcde')
print(url.update_query({'edit_id': 'abcde'}) # URL('https://velog.io/write?edit_id=abcde')
urllib이 가지고 있는 immutable 개념을 유지하면서, 기능을 잘 확장해 '더 편한 urllib' 느낌이 나게 설계되었다고 생각한다. 그러나 언어 자체가 immutable에 민감한 것도 아닌데 이렇게까지 immutable을 고집할 필요가 있나 싶었다. 내가 프로그래밍에 경험이 많지 않아서 든 생각일 수도 있겠지만, 이 이유 때문에 yarl에는 그렇게 정을 붙이지 못했다.
나는 조금 더 편하길 원했고, URL을 다루는 것에 대해 좋은 아이디어를 가지고 있는 사람이 한두명으로 끝나지 않을 것 같았고, 무려 'URL'을 다루는 라이브러리라면 star가 1000개 넘는 것도 분명 있을 것 같았다. 파이썬으로 URL 가지고 놀기 - furl 편으로 이어진다.
ㅎㅎ 흥미진진하네요~
다음편 기대 됩니다.