文章目录
简介用法函数原型源代码其他参考文献
简介
常用 urllib.parse.urlencode 进行 URL 的 get 请求参数拼接。
import urllib
.parse
url
= 'http://www.baidu.com/s'
query
= {
'wd': 'Python3标准库',
'ie': 'UTF-8'
}
print(url
+ '?' + urllib
.parse
.urlencode
(query
))
用法
import urllib
.parse
query
= {}
print(urllib
.parse
.urlencode
(query
))
query
= {'a': 1, 'b': 2}
print(urllib
.parse
.urlencode
(query
))
query
= (('a', 1), ('b', 2))
print(urllib
.parse
.urlencode
(query
))
query
= (('a', [1, 2]), ('b', [2, 3]))
print(urllib
.parse
.urlencode
(query
, doseq
=True))
query
= {b
'a': b
'1', b
'b': b
'2'}
print(urllib
.parse
.urlencode
(query
))
建议使用 dict
函数原型
def urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)
参数描述
query查询参数doseq序列元素是否单独转换safe安全默认值encoding编码errors错误默认值quote_via查询参数的成份是str时,safe, encoding, errors传递给的指定函数默认为quote_plus(),加强版quote()
源代码
def quote(string
, safe
='/', encoding
=None, errors
=None):
"""quote('abc def') -> 'abc%20def'
URL的每个部分,如路径信息、查询等,若遇到保留关键字必须用引号括起来。
RFC 2396 统一资源标识符(URI)的通用语法列出了以下保留关键字。
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
"$" | ","
每个字段都保留在URL中,但不是所有字符都保留在字段中。(Each of these characters is reserved in some component of a URL, but not necessarily in all of them.)
默认情况下,quote()用于URL的path部分。因此,它不会对'/'进行编码。此字符是保留的,但在典型的用法中,quote函数会在使用现有斜杠字符作为保留字符的path部分上调用。
string和safe可以是str或bytes对象。如果字符串是字节对象,则不能指定encoding和errors。
可选的encoding和errors指定如何处理string。encode方法接受非ASCII字符。默认情况下,encoding='utf-8',errors='strict'(不支持的字符会引发UnicodeEncodeError)。
"""
if isinstance(string
, str):
if not string
:
return string
if encoding
is None:
encoding
= 'utf-8'
if errors
is None:
errors
= 'strict'
string
= string
.encode
(encoding
, errors
)
else:
if encoding
is not None:
raise TypeError
("quote() doesn't support 'encoding' for bytes")
if errors
is not None:
raise TypeError
("quote() doesn't support 'errors' for bytes")
return quote_from_bytes
(string
, safe
)
def quote_plus(string
, safe
='', encoding
=None, errors
=None):
"""类似quote(),可以将' '替换为'+'。原始字符串中的加号将进行转义,除非它们包含在safe中。safe没有默认为'/'。
"""
if ((isinstance(string
, str) and ' ' not in string
) or
(isinstance(string
, bytes) and b
' ' not in string
)):
return quote
(string
, safe
, encoding
, errors
)
if isinstance(safe
, str):
space
= ' '
else:
space
= b
' '
string
= quote
(string
, safe
+ space
, encoding
, errors
)
return string
.replace
(' ', '+')
def urlencode(query
, doseq
=False, safe
='', encoding
=None, errors
=None,
quote_via
=quote_plus
):
"""将一个dict或二元素的tuple编码为一个URL查询字符串。
如果query中所有值都是序列,并且doseq为True,那么每个序列元素都被转换为一个单独的参数
如果query是一个二元素的tuple序列,则输出中参数的顺序将与输入中参数的顺序匹配。
查询参数的成份可以是字符串类型,也可以是字节类型。
当查询参数的成份是str时,safe, encoding, errors传递给指定的函数quote_via。
"""
if hasattr(query
, "items"):
query
= query
.items
()
else:
try:
if len(query
) and not isinstance(query
[0], tuple):
raise TypeError
except TypeError
:
ty
, va
, tb
= sys
.exc_info
()
raise TypeError
("not a valid non-string sequence "
"or mapping object").with_traceback
(tb
)
l
= []
if not doseq
:
for k
, v
in query
:
if isinstance(k
, bytes):
k
= quote_via
(k
, safe
)
else:
k
= quote_via
(str(k
), safe
, encoding
, errors
)
if isinstance(v
, bytes):
v
= quote_via
(v
, safe
)
else:
v
= quote_via
(str(v
), safe
, encoding
, errors
)
l
.append
(k
+ '=' + v
)
else:
for k
, v
in query
:
if isinstance(k
, bytes):
k
= quote_via
(k
, safe
)
else:
k
= quote_via
(str(k
), safe
, encoding
, errors
)
if isinstance(v
, bytes):
v
= quote_via
(v
, safe
)
l
.append
(k
+ '=' + v
)
elif isinstance(v
, str):
v
= quote_via
(v
, safe
, encoding
, errors
)
l
.append
(k
+ '=' + v
)
else:
try:
x
= len(v
)
except TypeError
:
v
= quote_via
(str(v
), safe
, encoding
, errors
)
l
.append
(k
+ '=' + v
)
else:
for elt
in v
:
if isinstance(elt
, bytes):
elt
= quote_via
(elt
, safe
)
else:
elt
= quote_via
(str(elt
), safe
, encoding
, errors
)
l
.append
(k
+ '=' + elt
)
return '&'.join
(l
)
其他
查询字符串 a=1&a=2有什么用?服务器会拿最后的值作为a的值。
import tornado
.web
import tornado
.ioloop
import tornado
.httpserver
from tornado
.options
import define
, options
, parse_command_line
define
("port", default
=8888, help="运行端口", type=int)
class TestHandler(tornado
.web
.RequestHandler
):
def get(self
):
print(self
.get_argument
('a'))
if __name__
== "__main__":
parse_command_line
()
print("http://localhost:{}/?a=1&a=2".format(options
.port
))
app
= tornado
.web
.Application
(
handlers
=[
(r
"/", TestHandler
),
],
)
http_server
= tornado
.httpserver
.HTTPServer
(app
)
http_server
.listen
(options
.port
)
tornado
.ioloop
.IOLoop
.instance
().start
()
参考文献
urllib.parse.urlencode