urlparse()仅结构拆分,query字段为原始字符串,须用parse_qs()或parse_qsl()解析为字典或元组列表,二者均自动解码且支持重复键。

urlparse() 解析 URL 时 query 字段是 raw string,需要手动 parse_qs()
直接用 urlparse() 拿到的 query 是一整段未解码的字符串(如 "name=张三&city=%E4%B8%8A%E6%B5%B7"),它不会自动转成字典。你得额外调用 parse_qs() 或 parse_qsl() 处理。
常见错误是以为 urlparse().query 已经是结构化数据,结果直接 .get("name") 报错。
-
parse_qs()返回{key: [value]}形式,适合处理可能重复的参数(如?tag=a&tag=b) -
parse_qsl()返回[(key, value)]列表,更轻量,且默认不编码空格为+(parse_qs()会) - 两者都默认进行 URL 解码,无需自己调
unquote()
from urllib.parse import urlparse, parse_qs
url = "https://example.com/search?q=python+url&sort=date"
parsed = urlparse(url)
params = parse_qs(parsed.query) # {'q': ['python url'], 'sort': ['date']}
urlencode() 构建 query string 时注意 list 和 None 的行为
urlencode() 对输入类型很敏感:传 dict 会把每个 key 的 value 当作单值;传 list 或 tuple 才能生成重复参数。
容易踩的坑是传入含 None 的字典——urlencode() 默认跳过 None 值,但不会报错,导致参数“静默丢失”。
立即学习“Python免费学习笔记(深入)”;
- 要保留空值,显式传
doseq=True并确保 value 是字符串(None仍会被忽略) - 生成
?a=1&a=2必须用urlencode([('a', 1), ('a', 2)], doseq=True),不能用{'a': [1, 2]}—— 后者在doseq=False下只取第一个 - 中文或特殊字符会自动编码,不需要预先
quote()
from urllib.parse import urlencode
urlencode({'q': 'hello world', 'page': 2}) # 'q=hello+world&page=2'
urlencode([('f', 'a'), ('f', 'b')], doseq=True) # 'f=a&f=b'
quote() 和 unquote() 不等于 URL path 编码的全部逻辑
很多人用 quote() 处理路径片段(如 /user/张三),但默认它会编码斜杠 /,导致 %2F,破坏 URL 结构。
关键点在于:path 编码应排除 /、.、~ 等安全字符;而 query 中的 =、& 是分隔符,也不该被编码——这些细节 quote() 不懂,得靠参数控制。
- 对路径使用
quote(path, safe='/'),保留斜杠 - 对查询参数的单个 value,用默认
quote(value)即可(它默认safe='/',但 query 里本就不该有/) -
unquote()能正确还原所有%xx,但无法修复双重编码(如%2520是%20被又编了一次)
拼接 URL 时别直接字符串 +,优先用 urlunparse()
手写 base + '?' + urlencode(params) 在 base 已带 query 或 fragment 时极易出错。比如 https://a.com?x=1#top 加新参数,必须先拆解再合并,否则 fragment 错位或 query 混乱。
urlunparse() 是唯一能安全重建完整 URL 的方式,它接受 6 元组:(scheme, netloc, path, params, query, fragment)。其中 params 是 path 后面的分号参数(极少用),一般设空字符串。
- 先
urlparse()拆,改query字段,再urlunparse()合——这是原子操作 - 不要尝试用正则或
str.replace()修改 query,URL 编码会让匹配不可靠 - 如果只是加参数,推荐封装一个函数,内部做
parse_qs → update → urlencode流程
真正难的不是语法,而是边界情况:空值怎么处理、重复键要不要保留、编码是否嵌套、fragment 是否随 query 变化迁移——这些都得在具体业务里逐条对齐。


















