Skip to main content

21.8. urllib.parse —将URL解析到组件中

源代码: Lib/urllib/parse.py


此模块定义了一个标准接口,用于在组件(寻址方案,网络位置,路径等)中打断统一资源定位符(URL)字符串,将组件组合回URL字符串,并将“相对URL”转换为给定“基本URL”的绝对URL。

该模块被设计为匹配相对统一资源定位符上的因特网RFC。它支持以下URL方案:fileftpgopherhdlhttphttpsimapmailtommsnewsnntpprosperorsyncrtsprtspusftpshttpsipsipssnewssvnsvn+sshtelnetwaiswswss

urllib.parse 模块定义了分为两大类的功能:URL解析和URL引用。这些内容将在以下部分中详细介绍。

21.8.1. 网址解析

URL解析函数专注于将URL字符串拆分为其组件,或将URL组件组合到URL字符串中。

urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)

将URL解析为六个组件,返回一个6元组。这对应于URL的一般结构:scheme://netloc/path;parameters?query#fragment。每个元组项都是一个字符串,可能为空。组件不会在较小的部分中分解(例如,网络位置是单个字符串),并且不扩展%转义。如上所示的分隔符不是结果的一部分,除了 path 组件中的前导斜杠(如果存在,则保留)。例如:

>>> from urllib.parse import urlparse
>>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html')
>>> o   
ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
            params='', query='', fragment='')
>>> o.scheme
'http'
>>> o.port
80
>>> o.geturl()
'http://www.cwi.nl:80/%7Eguido/Python.html'

遵循 RFC 1808 中的语法规范,urlparse仅在由“//”正确引入时识别netloc。否则,输入被假定为相对URL,并且因此以路径分量开始。

>>> from urllib.parse import urlparse
>>> urlparse('//www.cwi.nl:80/%7Eguido/Python.html')
ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html',
           params='', query='', fragment='')
>>> urlparse('www.cwi.nl/%7Eguido/Python.html')
ParseResult(scheme='', netloc='', path='www.cwi.nl/%7Eguido/Python.html',
           params='', query='', fragment='')
>>> urlparse('help/Python.html')
ParseResult(scheme='', netloc='', path='help/Python.html', params='',
           query='', fragment='')

scheme 参数提供默认寻址方案,仅在URL不指定时使用。它应该是与 urlstring 相同的类型(文本或字节),除了始终允许默认值 '',并且如果适当,将自动转换为 b''

如果 allow_fragments 参数为false,则无法识别片段标识符。相反,它们将作为路径,参数或查询组件的一部分进行解析,并将 fragment 设置为返回值中的空字符串。

返回值实际上是 tuple 子类的一个实例。此类具有以下额外的只读方便属性:

属性

指数

值(如果不存在)

scheme

0

URL方案说明符

scheme 参数

netloc

1

网络位置部分

空字符串

path

2

分层路径

空字符串

params

3

最后路径元素的参数

空字符串

query

4

查询组件

空字符串

fragment

5

片段标识符

空字符串

username

 

用户名

None

password

 

密码

None

hostname

 

主机名(小写)

None

port

 

端口号为整数(如果存在)

None

如果在URL中指定了无效的端口,则读取 port 属性将产生 ValueError。有关结果对象的更多信息,请参阅 结构解析结果 部分。

在 3.2 版更改: 添加了IPv6 URL解析功能。

在 3.3 版更改: 现在,根据 RFC 3986,对所有URL方案(除非 allow_fragment 为false)解析片段。以前,支持分段的方案的白名单存在。

在 3.6 版更改: 超出范围的端口号现在提高 ValueError,而不是返回 None

urllib.parse.parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace')

解析作为字符串参数(application/x-www-form-urlencoded 类型的数据)提供的查询字符串。数据作为字典返回。字典键是唯一的查询变量名,值是每个名称的值列表。

可选参数 keep_blank_values 是指示百分比编码查询中的空白值是否应被视为空白字符串的标志。 true值表示空白应保留为空白字符串。默认的false值表示将空值忽略并视为未包括空值。

可选参数 strict_parsing 是指示如何处理解析错误的标志。如果为false(默认值),则会忽略错误。如果为true,错误会引发 ValueError 异常。

可选的 encodingerrors 参数指定如何将百分比编码的序列解码为Unicode字符,如 bytes.decode() 方法所接受的。

使用 urllib.parse.urlencode() 函数(将 doseq 参数设置为 True)将这些字典转换为查询字符串。

在 3.2 版更改: 添加 encodingerrors 参数。

urllib.parse.parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace')

解析作为字符串参数(application/x-www-form-urlencoded 类型的数据)提供的查询字符串。数据作为名称,值对的列表返回。

可选参数 keep_blank_values 是指示百分比编码查询中的空白值是否应被视为空白字符串的标志。 true值表示空白应保留为空白字符串。默认的false值表示将空值忽略并视为未包括空值。

可选参数 strict_parsing 是指示如何处理解析错误的标志。如果为false(默认值),则会忽略错误。如果为true,错误会引发 ValueError 异常。

可选的 encodingerrors 参数指定如何将百分比编码的序列解码为Unicode字符,如 bytes.decode() 方法所接受的。

使用 urllib.parse.urlencode() 函数将这些对列表转换为查询字符串。

在 3.2 版更改: 添加 encodingerrors 参数。

urllib.parse.urlunparse(parts)

urlparse() 返回的元组构造一个URL。 parts 参数可以是任何六项可迭代。如果最初分析的URL具有不必要的分隔符(例如,具有空查询的 ?; RFC声明这些分隔符是等效的),则这可能导致稍微不同但是等效的URL。

urllib.parse.urlsplit(urlstring, scheme='', allow_fragments=True)

这与 urlparse() 类似,但不会从URL中分离参数。如果想要将更多最近的URL语法允许将参数应用于URL的 path 部分的每个段(参见 RFC 2396),则这通常应当被用来代替 urlparse()。需要单独的功能来分离路径段和参数。此函数返回一个5元组:(寻址方案,网络位置,路径,查询,片段标识符)。

返回值实际上是 tuple 子类的一个实例。此类具有以下额外的只读方便属性:

属性

指数

值(如果不存在)

scheme

0

URL方案说明符

scheme 参数

netloc

1

网络位置部分

空字符串

path

2

分层路径

空字符串

query

3

查询组件

空字符串

fragment

4

片段标识符

空字符串

username

 

用户名

None

password

 

密码

None

hostname

 

主机名(小写)

None

port

 

端口号为整数(如果存在)

None

如果在URL中指定了无效的端口,则读取 port 属性将产生 ValueError。有关结果对象的更多信息,请参阅 结构解析结果 部分。

在 3.6 版更改: 超出范围的端口号现在提高 ValueError,而不是返回 None

urllib.parse.urlunsplit(parts)

urlsplit() 返回的元组的元素组合成一个完整的URL作为字符串。 parts 参数可以是任何五项可迭代。如果最初分析的URL具有不必要的分隔符(例如,带有空查询的?,RFC声明这些分隔符是等效的),这可能会导致稍有不同,但是等效的URL。

urllib.parse.urljoin(base, url, allow_fragments=True)

通过将“基本URL”(base)与另一个网址(url)组合构建完整(“绝对”)网址。非正式地,这使用基本URL的组件,特别是寻址方案,网络位置和(部分)路径,以在相对URL中提供缺失的组件。例如:

>>> from urllib.parse import urljoin
>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', 'FAQ.html')
'http://www.cwi.nl/%7Eguido/FAQ.html'

allow_fragments 参数具有与 urlparse() 相同的含义和默认值。

注解

如果 url 是绝对URL(即,以 //scheme:// 开头),url 的主机名和/或方案将存在于结果中。例如:

>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html',
...         '//www.python.org/%7Eguido')
'http://www.python.org/%7Eguido'

如果您不想要这种行为,请使用 urlsplit()urlunsplit() 预处理 url,删除可能的 schemenetloc 部分。

在 3.5 版更改: 更新行为以匹配 RFC 3986 中定义的语义。

urllib.parse.urldefrag(url)

如果 url 包含片段标识符,则返回没有片段标识符的 url 的修改版本,并且片段标识符作为单独的字符串。如果 url 中没有片段标识符,则返回未修改的 url 和空字符串。

返回值实际上是 tuple 子类的一个实例。此类具有以下额外的只读方便属性:

属性

指数

值(如果不存在)

url

0

没有片段的网址

空字符串

fragment

1

片段标识符

空字符串

有关结果对象的更多信息,请参阅 结构解析结果 部分。

在 3.2 版更改: 结果是一个结构化对象,而不是一个简单的2元组。

21.8.2. 解析ASCII编码字节

URL解析函数最初设计为仅对字符串操作。在实践中,能够操作正确引用和编码的URL作为ASCII字节序列是有用的。因此,除了 str 对象之外,该模块中的URL解析函数都对 bytesbytearray 对象进行操作。

如果传入 str 数据,结果也将只包含 str 数据。如果传入 bytesbytearray 数据,结果将只包含 bytes 数据。

尝试在单个函数调用中混合 str 数据与 bytesbytearray 将导致 TypeError 被引发,而尝试传递非ASCII字节值将触发 UnicodeDecodeError

为了支持在 strbytes 之间更容易地转换结果对象,来自URL解析函数的所有返回值提供 encode() 方法(当结果包含 str 数据时)或 decode() 方法(当结果包含 bytes 数据时)。这些方法的签名与相应的 strbytes 方法的签名(除了默认编码是 'ascii' 而不是 'utf-8')相匹配。每个产生包含 bytes 数据(对于 encode() 方法)或 str 数据(对于 decode() 方法)的对应类型的值。

需要在可能包含非ASCII数据的可能不正确引用的URL上操作的应用程序需要在调用URL解析方法之前自己从字节解码为字符。

此部分中描述的行为仅适用于URL解析函数。在生成或使用字节序列时,URL引用函数使用自己的规则,如各个URL引用函数的文档中所述。

在 3.2 版更改: URL解析函数现在接受ASCII编码的字节序列

21.8.3. 结构解析结果

来自 urlparse()urlsplit()urldefrag() 函数的结果对象是 tuple 类型的子类。这些子类添加了文档中为这些函数列出的属性,上一节中描述的编码和解码支持以及一个附加方法:

urllib.parse.SplitResult.geturl()

以字符串形式返回原始URL的重新组合版本。这可能不同于原始URL,因为方案可以归一化为小写,并且可以丢弃空组件。具体来说,将删除空参数,查询和片段标识符。

对于 urldefrag() 结果,将只删除空片段标识符。对于 urlsplit()urlparse() 结果,将对由此方法返回的URL进行所有标注的更改。

如果通过原始解析函数传回,此方法的结果保持不变:

>>> from urllib.parse import urlsplit
>>> url = 'HTTP://www.Python.org/doc/#'
>>> r1 = urlsplit(url)
>>> r1.geturl()
'http://www.Python.org/doc/'
>>> r2 = urlsplit(r1.geturl())
>>> r2.geturl()
'http://www.Python.org/doc/'

以下类提供了在 str 对象上操作时的结构化解析结果的实现:

class urllib.parse.DefragResult(url, fragment)

包含 str 数据的 urldefrag() 结果的具体类。 encode() 方法返回 DefragResultBytes 实例。

3.2 新版功能.

class urllib.parse.ParseResult(scheme, netloc, path, params, query, fragment)

包含 str 数据的 urlparse() 结果的具体类。 encode() 方法返回 ParseResultBytes 实例。

class urllib.parse.SplitResult(scheme, netloc, path, query, fragment)

包含 str 数据的 urlsplit() 结果的具体类。 encode() 方法返回 SplitResultBytes 实例。

以下类提供在 bytesbytearray 对象上操作时的解析结果的实现:

class urllib.parse.DefragResultBytes(url, fragment)

包含 bytes 数据的 urldefrag() 结果的具体类。 decode() 方法返回 DefragResult 实例。

3.2 新版功能.

class urllib.parse.ParseResultBytes(scheme, netloc, path, params, query, fragment)

包含 bytes 数据的 urlparse() 结果的具体类。 decode() 方法返回 ParseResult 实例。

3.2 新版功能.

class urllib.parse.SplitResultBytes(scheme, netloc, path, query, fragment)

包含 bytes 数据的 urlsplit() 结果的具体类。 decode() 方法返回 SplitResult 实例。

3.2 新版功能.

21.8.4. 网址引用

URL引用函数专注于获取程序数据,并通过引用特殊字符和适当编码非ASCII文本,使其安全用作URL组件。它们还支持反转这些操作以从URL组件的内容重新创建原始数据,如果该任务尚未被上面的URL解析函数覆盖。

urllib.parse.quote(string, safe='/', encoding=None, errors=None)

使用 %xx 转义替换 string 中的特殊字符。字母,数字和字符 '_.-' 从不引用。默认情况下,此函数用于引用URL的路径部分。可选的 safe 参数指定不应引用的其他ASCII字符 - 其默认值为 '/'

string 可以是 strbytes

可选的 encodingerrors 参数指定如何处理非ASCII字符,如 str.encode() 方法所接受。 encoding 默认为 'utf-8'errors 默认为 'strict',意味着不支持的字符提高 UnicodeEncodeError。如果 stringbytes 或提出 TypeError,则不得提供 encodingerrors

注意,quote(string, safe, encoding, errors) 等同于 quote_from_bytes(string.encode(encoding, errors), safe)

示例:quote('/El Niño/') 产生 '/El%20Ni%C3%B1o/'

urllib.parse.quote_plus(string, safe='', encoding=None, errors=None)

quote() 一样,也可以用加号替换空格,这是在构建查询字符串以进入URL时引用HTML表单值所必需的。加号在原始字符串中的符号被转义,除非它们包括在 safe 中。它也没有 safe 默认为 '/'

示例:quote_plus('/El Niño/') 产生 '%2FEl+Ni%C3%B1o%2F'

urllib.parse.quote_from_bytes(bytes, safe='/')

quote(),但是接受 bytes 对象而不是 str,并且不执行字符串到字节的编码。

示例:quote_from_bytes(b'a&\xef') 产生 'a%26%EF'

urllib.parse.unquote(string, encoding='utf-8', errors='replace')

用其单字符等效值替换 %xx 转义。可选的 encodingerrors 参数指定如何将百分比编码序列解码为Unicode字符,如 bytes.decode() 方法所接受。

string 必须是 str

encoding 默认为 'utf-8'errors 默认为 'replace',意味着无效序列被占位符字符替换。

示例:unquote('/El%20Ni%C3%B1o/') 产生 '/El Niño/'

urllib.parse.unquote_plus(string, encoding='utf-8', errors='replace')

unquote() 一样,也可以用空格替换加号,这是为了取消引用HTML表单值所必需的。

string 必须是 str

示例:unquote_plus('/El+Ni%C3%B1o/') 产生 '/El Niño/'

urllib.parse.unquote_to_bytes(string)

%xx 转义替换为其等效的单八位字节,并返回一个 bytes 对象。

string 可以是 strbytes

如果是 strstring 中的非转义非ASCII字符将编码为UTF-8字节。

示例:unquote_to_bytes('a%26%EF') 产生 b'a&\xef'

urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)

将映射对象或两元素元组序列(可能包含 strbytes 对象)转换为百分比编码的ASCII文本字符串。如果结果字符串要用作具有 urlopen() 函数的POST操作的 data,则它应该被编码为字节,否则将导致 TypeError

结果字符串是由 '&' 字符分隔的一系列 key=value 对,其中 keyvalue 都使用 quote_via 函数引用。默认情况下,quote_plus() 用于引用值,这意味着空格被引用为 '+' 字符,而“/”字符被编码为 %2F,它遵循GET请求(application/x-www-form-urlencoded)的标准。可以作为 quote_via 传递的备用函数是 quote(),它将将空格编码为 %20,而不编码“/”字符。要最大限度地控制引用的内容,请使用 quote 并指定 safe 的值。

当使用两元素元组的序列作为 query 参数时,每个元组的第一个元素是键,第二个元素是值。 value元素本身可以是一个序列,在这种情况下,如果可选参数 doseq 求值为 True,则为键的值序列的每个元素生成由 '&' 分隔的单独 key=value 对。编码字符串中参数的顺序将匹配序列中参数元组的顺序。

safeencodingerrors 参数被传递到 quote_viaencodingerrors 参数仅当查询元素是 str 时被传递)。

要反转此编码过程,在此模块中提供 parse_qs()parse_qsl() 以将查询字符串解析为Python数据结构。

请参阅 urllib示例 以了解如何使用urlencode方法来生成URL的查询字符串或POST的数据。

在 3.2 版更改: 查询参数支持字节和字符串对象。

3.5 新版功能: quote_via 参数。

参见

RFC 3986 - 统一资源标识符

这是当前标准(STD66)。对urllib.parse模块的任何更改都应符合此要求。可以观察到某些偏差,这主要是为了向后兼容性目的,并且对于在主要浏览器中通常观察到的某些事实解析要求。

RFC 2732 - URL中的字面IPv6地址的格式。

这指定IPv6 URL的解析要求。

RFC 2396 - 统一资源标识符(URI):通用语法

描述统一资源名称(URN)和统一资源定位符(URL)的通用句法要求的文档。

RFC 2368 - mailto URL方案。

解析mailto URL方案的要求。

RFC 1808 - 相对统一资源定位符

此征求意见稿包括加入绝对和相对网址的规则,包括管理边境案件处理的相当数量的“异常例子”。

RFC 1738 - 统一资源定位符(URL)

这指定绝对URL的形式语法和语义。