跳到正文
效率工具实用笔记关于本站
效率工具

给网址添加查询参数:用 urlencode 处理多值 doseq 与特殊字符

约 7 分钟阅读AI 辅助整理

手工拼查询串容易漏掉转义和重复键。本文只构造自建 example.com 网址,用 urlencode 生成查询串,讲清 doseq 处理多值、空格与斜杠等特殊字符的编码差异,以及如何用 parse_qs 回读检查结果。

本文要点

  1. 先看最简单的输入输出

  2. 同一个参数名带多个值,是查询串里很常见的需求

  3. 特殊字符的处理是这套做法最值得单独核对的部分

给网址添加查询参数:用 urlencode 处理多值 doseq 与特殊字符的知识要点示意图
依据已审核正文摘取要点制作的示意图,非实物照片;请结合正文中的条件与范围阅读。要点摘自已审核正文;完整条件与说明见正文。查看高清图解 ↗
本文目录

先看手工拼接会在哪两处出错

给网址加查询参数,最省事的写法是拿字符串直接拼:base + "?" + "q=" + value。这个写法在两种情况下会出问题。

第一种是值里带特殊字符。空格、斜杠、中文、&、= 这些字符在查询串里有各自的含义,直接拼进去,接收方读到的参数边界就和你以为的不一样。

第二种是同一个参数名要带多个值。手工拼时容易写成 q=a&q=b 却忘了逐个转义,或者把多个值硬塞进一个字符串,导致回读时拆不出原来的几项。

urllib.parse.urlencode 就是为这两件事准备的:它接收一个键值对序列或映射,返回已经转义好的查询串文本。本文只构造自建 example.com 网址,不发送任何网络请求,也不读写文件。下面所有参数名和参数值都是练习用的自建数据。

动手前建议在练习目录里新建脚本,例如 exercise/url_demo.py,不要拿正在用的工具直接改。

单值参数:urlencode 接收什么、返回什么

先看最简单的输入输出。urlencode 的入参是键值对,出参是一个字符串,不含开头的问号。

from urllib.parse import urlencode

params = {"q": "茶 样", "page": "2"}
print(urlencode(params))

输出形如 q=%E8%8C%B6+%E6%A0%B7&page=2。这里能看到两件事:中文被转成了百分号编码,空格被转成了加号。

加号这个结果来自默认的 quote_via=quote_plus。文档说明,urlencode 默认用 quote_plus 处理,而 quote_plus 会把空格转成加号;如果改用 quote,空格会转成 %20。两者对空格的处理不同,选哪个要和接收方约定一致,不能两边各用一套。

另一个容易忽略的点:urlencode 不负责拼问号。你要自己决定是把它接在 ? 后面,还是接在已有的 & 后面。它只产出参数部分。

多值参数:doseq=True 才展开序列

同一个参数名带多个值,是查询串里很常见的需求。默认情况下,urlencode 会把值当成一个整体处理。

from urllib.parse import urlencode

params = {"tag": ["red", "green"]}
print(urlencode(params))
print(urlencode(params, doseq=True))

第一次输出会把列表的字符串表示塞进一个值里,形如 tag=%5B%27red%27%2C+%27green%27%5D,这不是你想要的多值形式。加上 doseq=True 之后,输出变成 tag=red&tag=green,同一个键重复出现,每个值各自转义。

doseq 的适用条件要记清:它只对“值本身是序列”的情况展开。如果值是一个字符串,即使它看起来像多个值,也不会被拆开。也就是说,["a", "b"] 会被展开,"a,b" 不会。

多值参数回读时,parse_qs 默认会把每个键的值收集成列表,所以 tag=red&tag=green 读回来是 {"tag": ["red", "green"]}。这一点和单值参数不同,检查时要留意类型。

特殊字符:空格、斜杠和中文各转成什么

特殊字符的处理是这套做法最值得单独核对的部分。

空格:默认 quote_plus 转成加号;改用 quote 转成 %20。回读时 parse_qs 会把加号还原成空格,所以两种写法读回来都是空格,但文本形态不同。

斜杠:quote 和 quote_plus 默认都不把斜杠当作安全字符,斜杠会被转成 %2F。这一点在把路径片段当参数值传时尤其要注意,不能想当然认为斜杠会原样保留。

中文:按 UTF-8 逐字节转成百分号编码,一个汉字通常对应三个 %XX 片段。

& 和 =:这两个字符在查询串里是分隔符,作为值出现时会被转义,避免把参数边界弄乱。

下面这段把几种字符放在一起对照:

from urllib.parse import urlencode

params = {"path": "a/b c", "q": "茶&样"}
print(urlencode(params))

输出里斜杠变成 %2F,空格变成加号,& 变成 %26。核对时逐段看,不要只看整体像不像。

回读检查:用 parse_qs 确认参数没走样

生成查询串之后,建议回读一遍再使用。parse_qs 接收查询串,返回一个字典,键是参数名,值是参数值列表。

from urllib.parse import urlencode, parse_qs

params = {"tag": ["red", "green"], "q": "茶 样"}
qs = urlencode(params, doseq=True)
print(qs)
print(parse_qs(qs))

回读结果里,tag 对应一个两项列表,q 对应一个单项列表,空格已经还原。用这个结果和你最初的输入对照,就能确认多值有没有被拆散、特殊字符有没有还原正确。

一个检查习惯:把 parse_qs 的结果和原始 params 并排看,重点核对三处——多值参数的项数、含空格参数的值、含斜杠或 & 参数的值。这三处是最容易出偏差的地方。

拼进完整网址时的顺序与边界

把查询串接到自建 example.com 网址上时,先判断这个网址原本有没有查询串。没有查询串,用 ? 连接;已经有查询串,用 & 连接。这一步用字符串判断即可,不要盲目追加。

base = "https://example.com/search"
qs = urlencode({"q": "茶 样"})
url = base + "?" + qs
print(url)

几个需要留意的边界:urlencode 只负责把数据转成查询串文本,它不判断参数名或参数值在你的业务里是否合理;urlsplit 和 urlparse 不做输入校验,文档明确建议在值可能用于有安全影响的场景时,由调用方自己做验证;本文示例里的中文、空格和斜杠都是自建练习数据,不是对某个真实站点行为的记录。实际使用时,以你手上那款工具或接口的说明为准。

观看知识要点视频 18 秒

18秒无旁白要点导览,文字来自已审核正文;完整步骤、条件及参考资料见下方。

参考资料

以下原始资料提供本文依据;请结合日期、适用条件和产品说明查阅。

请结合原始资料的适用条件阅读。

返回效率工具 →