PythiloLesson 2 of 5 · progress kept in this browser

Parsing a URL

Never take URLs apart with split. Encoding rules and optional parts make that fragile. urllib.parse handles them.

from urllib.parse import (
    urlsplit, parse_qsl, urlencode)

u = urlsplit(
    "https://a.io:8000/s?q=a+b&p=2#top")
print(u.scheme, u.hostname, u.port)
print(u.path, u.query, u.fragment)
print(parse_qsl(u.query))
# [('q', 'a b'), ('p', '2')]
print(urlencode({"q": "a b"}))
# q=a+b
  • u.port is None when the URL does not state one.
  • parse_qsl drops parameters with blank values unless you pass keep_blank_values=True.
  • parse_qs returns a dict of lists, since a key may repeat.
  • A split URL is a named tuple, so u._replace(query="x=1").geturl() builds a new URL with one part changed.

quote and unquote handle percent-encoding, and urljoin resolves relative links.

Your task

Write query_params(url) returning a dict from each key to its first value, keeping blank values. Write add_param(url, key, value) setting one query parameter, replacing it in place if present, otherwise appending, and leaving other URL parts alone. Write host_and_port(url) returning (host, port), using 443 for https and 80 for http when none is given.

Next: WSGI