urllib.parse divide URL, interpreta query strings y aplica percent-encoding. urlsplit mantiene separados esquema, autoridad, ruta, consulta y fragmento; urlencode produce parámetros escapados correctamente.

from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit

parts = urlsplit("https://example.com/search?q=python&page=2")
query = parse_qs(parts.query)
query["page"] = ["3"]

new_url = urlunsplit(parts._replace(query=urlencode(query, doseq=True)))
print(new_url)

Cómo usarlo con seguridad

El parser no garantiza que una URL sea segura. Para redirecciones o peticiones, admite solo esquemas esperados, valida el hostname y considera la resolución DNS y las direcciones internas. Recuerda que urljoin acepta URL absolutas.

Para reforzar la base, consulta guía de collections en Python y guía de type hints.

La documentación oficial de Python, consultada el 22 de julio de 2026, describe la API, los casos límite y la compatibilidad entre versiones.