Web 编程中由于需要用 Form 或 URL 来传递参数,所以必然会有 urlencode 和 urldecode 的操作,Python Web 也不例外。Python 对 URL 的编解码操作提供了 urllib
模块,下面例子中所使用的 Python 版本是 3.6.7,不同的 Python 版本可能略有差异。
简面言之本文就是关于以下六个函数的使用,更多关于 urllib
的用法请自行进一步研究。
from urllib.parse import urlencode, parse_ql, quote, quote_plus, unquote, unquote_plus
为什么两个 urlencode 和 urldecode 操作会涉及到六个函数的应用呢,分别来讲述
1. urlencode
Python 的 urllib
直接提供了 urlencode
函数,它的操作数是一个字典
1 2 |
>>> urlencode({'user': "O'Neil", 'message': 'hello world'}) 'user=O%27Neil&message=hello+world' |
字典中的多个 key-value 值用 &
连接成一个查询字符串。
并且注意到这里的 urlencode
函数,特殊字符编码为 %xx
的形式,并且空格转换为加号 +
,而不是编码为 %20
, 这有可能造成解码时不一致而把加号 +
作为一个实际的字符来处理。
如果希望空格编译编码为 %20
, 而非加号 +
的话,调用 urlencode
函数可以由参数 quote_via
指定为 quote
,它的默认值为 quote_plus
,即空格替换为加号 +
。
1 2 |
>>> urlencode({'user': "O'Neil", 'message': 'hello world'}, quote_via=quote) 'user=O%27Neil&message=hello%20world' |
urlencode
是针对字典的操作,也可以单独对一个字符串值进行编码,基于是否把空格替换为加号 +
的不同行为,分别有 quote
和 quote_plus
操作,分别看下面的例子
1 2 3 4 |
>>> quote("O'Neil,Hello World") 'O%27Neil%2CHello%20World' >>> quote_plus("O'Neil,Hello World") 'O%27Neil%2CHello+World' |
2. urldecode
urllib
并没有与 urlencode
函数相对应的 urldecode
函数名,实际上 urlencode
反作用的的函数是 parse_ql
,它把一个查询字符串转换为字典,而且还同时兼容空格的 %20
和 +
的两种表现形式。见下面的例子
1 2 3 4 |
>>> parse_qs('user=O%27Neil&message=hello%20world') {'user': ["O'Neil"], 'message': ['hello world']} >>> parse_qs('user=O%27Neil&message=hello+world') {'user': ["O'Neil"], 'message': ['hello world']} |
请留意 parse_ql
得到的字典的值是一个列表,因为 HTTP 的查询字符串中相同的 key 可以出现多次,如
1 2 |
>>> parse_qs('user=O%27Neil&message=hello%20world&message=Hello+World') {'user': ["O'Neil"], 'message': ['hello world', 'Hello World']} |
如果确定 querystring 中不会有重复的 key,可以对 parse_ql
得到的字典进一步转换
1 2 |
>>> {key: value[0] for (key, value) in parse_qs('user=O%27Neil&message=hello+world').items()} {'user': "O'Neil", 'message': 'hello world'} |
与 quote
和 quote_plus
相对应的操作有 unquote
和 unquote_plus
应该就好理解了,也是单独对某个字符串的操作,直接看代码就好了
1 2 3 4 5 6 7 8 9 10 11 12 |
>>> unquote("O'lNeil,Hello%20World") "O'lNeil,Hello World" >>> unquote("O'lNeil,Hello+World") "O'lNeil,Hello+World" >>> unquote_plus("O'lNeil,Hello%20World") "O'lNeil,Hello World" >>> unquote_plus("O'lNeil,Hello+World") "O'lNeil,Hello World" >>> >>> unquote_plus('user=O%27Neil&message=hello+world') "user=O'Neil&message=hello world" |
unquote
无法把加号 +
还原为空格,而使用 unquote_plus
好像总是更保险。是否有 URL 中的加号不进行编码呢,保持为 +
?应该不会,加号 +
也不过是被编码为 %2B
而已。
同时,unquote
或 unquote_plus
对 &
符号是无害的,所以它也能直接对整个查询字符串进行解码。
本文链接 https://yanbin.blog/python-urlencode-urldecode/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
thanks