我应该使用urlparse还是urlsplit?
我应该使用哪一对URL 解析函数,为什么呢?
urlparse
和urlunparse
,还是urlsplit
和urlunsplit
?
3 个回答
正如文档所说
urlparse.urlparse
会返回一个包含6个元素的元组(还有一个额外的参数元组)
而urlparse.urlsplit
则返回一个包含5个元素的元组
属性 |索引 | 值 | 如果不存在则为
params | 3 | 最后路径元素的参数 | 空字符串
顺便提一下:根据[RFC2396](https://www.rfc-editor.org/rfc/rfc2396.html#appendix-C),在URL规范中,_参数_的定义是 > 对当前客户端应用程序进行了广泛测试,结果显示大多数已部署的系统并不使用“;”字符来表示后面的参数信息,并且路径段中出现分号并不会影响该段的相对解析。因此,参数已被移除作为一个单独的组件,现在可以出现在任何路径段中。它们对解析相对URI引用的算法没有影响。
根据你提供的文档,里面没有包含带有非空params
的例子,所以我也感到困惑,直到我找到了这个链接。
>>> urllib.parse.urlparse("http://example.com/pa/th;param1=foo;param2=bar?name=val#frag")
ParseResult(scheme='http', netloc='example.com', path='/pa/th', params='param1=foo;param2=bar', query='name=val', fragment='frag')
(一些背景故事,因为我被这个问题吸引了。)
我之前从没听说过“URL参数”这个说法,除了URL组件参数,比如/user/213/settings
或者查询参数/user?id=213
,我觉得这个概念基本上已经过时了。
最开始的时候,RFC 1738定义了HTTP URL,规定在path
中不能出现;
:
http://<host>:<port>/<path>?<searchpart>
在
<path>
和<searchpart>
组件中,“/”、“;”、“?”都是保留字符。
这里的;
在其他方案中有特殊含义,比如在ftp://的url-path
中:
<cwd1>/<cwd2>/.../<cwdN>/<name>;type=<typecode>
显然在1995年,RFC 1808定义了URL的params
,作为path
和query
之间的顶层组件:
<scheme>://<net_loc>/<path>;<params>?<query>#<fragment>
然后在1998年,RFC 2396定义了URI,规定它有相邻的顶层组件path
和query
:
<scheme>://<authority><path>?<query>
其中path
被定义为多个path_segments
,每个都可以包含param
:
path = [ abs_path | opaque_part ]
abs_path = "/" path_segments
path_segments = segment *( "/" segment )
segment = *pchar *( ";" param )
最后在2005年,RFC 3986废除了RFC 1808和2396,定义了URI
,与RFC 2396类似:
URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
hier-part = "//" authority path-abempty
/ path-absolute
/ path-rootless
/ path-empty
而;params
的特殊语法被认为是URI语法中的一个不透明部分,可能特定于HTTP(S)方案或某些特定的实现:
除了层次路径中的点段,通用语法认为路径段是不透明的。生成URI的应用程序通常使用在段中允许的保留字符来分隔特定于方案或解引用处理程序的子组件。例如,分号(“;”)和等号(“=”)这两个保留字符通常用于分隔适用于该段的参数和参数值。逗号(“,”)这个保留字符也常用于类似的目的。例如,一个URI生成器可能会使用“name;v=1.1”这样的段来表示对“name”版本1.1的引用,而另一个可能会使用“name,1.1”这样的段来表示同样的意思。参数类型可能由特定于方案的语义定义,但在大多数情况下,参数的语法是特定于URI解引用算法的实现的。
直接来自你自己链接的文档:
urllib.parse.urlsplit(urlstring, scheme='', allow_fragments=True)
这个函数和urlparse()
很像,但它不会把参数从网址中分开。如果你想使用更新的URL语法,允许在网址路径的每个部分添加参数(参考RFC 2396),那么一般应该使用这个函数,而不是urlparse()
。