urllib.parse 用于解析 URL?
源代碼: Lib/urllib/parse.py
該模塊定義了一個標準接口,用于將統(tǒng)一資源定位符(URL)字符串拆分為不同部分(協(xié)議、網絡位置、路徑等),或將各個部分組合回 URL 字符串,并將“相對 URL”轉換為基于給定的“基準 URL”的絕對 URL。
該模塊被設計為匹配針對相對統(tǒng)一資源定位符的因特網 RFC。 它支持下列 URL 類型: file, ftp, gopher, hdl, http, https, imap, mailto, mms, news, nntp, prospero, rsync, rtsp, rtspu, sftp, shttp, sip, sips, snews, svn, svn+ssh, telnet, wais, ws, wss.
urllib.parse 模塊定義的函數可分為兩個主要門類: URL 解析和 URL 轉碼。 這些函數將在以下各節(jié)中詳細說明。
URL 解析?
URL 解析函數用于將一個 URL 字符串分割成其組成部分,或者將 URL 的多個部分組合成一個 URL 字符串。
- urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)?
將一個 URL 解析為六個部分,返回一個包含 6 項的 named tuple。 這對應于 URL 的主要結構:
scheme://netloc/path;parameters?query#fragment。 每個元組項均為字符串,可能為空字符串。 這些部分不會再被拆分為更小的部分(例如,netloc 將為單個字符串),并且 % 轉義不會被擴展。 上面顯示的分隔符不會出現在結果中,只有 path 部分的開頭斜杠例外,它如果存在則會被保留。 例如:>>> from urllib.parse import urlparse >>> urlparse("scheme://netloc/path;parameters?query#fragment") ParseResult(scheme='scheme', netloc='netloc', path='/path;parameters', params='', query='query', fragment='fragment') >>> o = urlparse("http://docs.python.org:80/3/library/urllib.parse.html?" ... "highlight=params#url-parsing") >>> o ParseResult(scheme='http', netloc='docs.python.org:80', path='/3/library/urllib.parse.html', params='', query='highlight=params', fragment='url-parsing') >>> o.scheme 'http' >>> o.netloc 'docs.python.org:80' >>> o.hostname 'docs.python.org' >>> o.port 80 >>> o._replace(fragment="").geturl() 'http://docs.python.org:80/3/library/urllib.parse.html?highlight=params'
根據 RFC 1808 中的語法規(guī)范,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 參數給出了默認的協(xié)議,只有在 URL 未指定協(xié)議的情況下才會被使用。 它應該是與 urlstring 相同的類型(文本或字節(jié)串),除此之外默認值
''也總是被允許,并會在適當情況下自動轉換為b''。如果 allow_fragments 參數為假值,則片段標識符不會被識別。 它們會被解析為路徑、參數或查詢部分,在返回值中
fragment會被設為空字符串。返回值是一個 named tuple,這意味著它的條目可以通過索引或作為命名屬性來訪問,這些屬性是:
屬性
索引
值
值(如果不存在)
scheme0
URL 協(xié)議說明符
scheme 參數
netloc1
網絡位置部分
空字符串
path2
分層路徑
空字符串
params3
No longer used
always an empty string
query4
查詢組件
空字符串
fragment5
片段標識符
空字符串
username用戶名
password密碼
hostname主機名(小寫)
port端口號為整數(如果存在)
如果在 URL 中指定了無效的端口,讀取
port屬性將引發(fā)ValueError。 有關結果對象的更多信息請參閱 結構化解析結果 一節(jié)。在
netloc屬性中不匹配的方括號將引發(fā)ValueError。如果
netloc屬性中的字符在 NFKC 規(guī)范化下(如 IDNA 編碼格式所使用的)被分解成/,?,#,@或:則將引發(fā)ValueError。 如果在解析之前 URL 就被分解,則不會引發(fā)錯誤。與所有具名元組的情況一樣,該子類還有一些特別有用的附加方法和屬性。 其中一個方法是
_replace()。_replace()方法將返回一個新的 ParseResult 對象來將指定字段替換為新的值。>>> from urllib.parse import urlparse >>> u = urlparse('//www.cwi.nl:80/%7Eguido/Python.html') >>> u ParseResult(scheme='', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', params='', query='', fragment='') >>> u._replace(scheme='http') ParseResult(scheme='http', netloc='www.cwi.nl:80', path='/%7Eguido/Python.html', params='', query='', fragment='')
在 3.2 版更改: 添加了IPv6 URL解析功能。
在 3.3 版更改: 會對所有 URL 協(xié)議解析片段(除非 allow_fragment 為假值),依據 RFC 3986 的規(guī)范。 在之前版本中,存在一個支持片段的協(xié)議允許名單。
在 3.6 版更改: 超范圍的端口號現在會引發(fā)
ValueError,而不是返回None。在 3.8 版更改: 在 NFKC 規(guī)范化下會影響 netloc 解析的字符現在將引發(fā)
ValueError。
- urllib.parse.parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')?
解析以字符串參數形式(類型為 application/x-www-form-urlencoded 的數據)給出的查詢字符串。 返回字典形式的數據。 結果字典的鍵為唯一的查詢變量名而值為每個變量名對應的值列表。
可選參數 keep_blank_values 是一個旗標,指明是否要將以百分號轉碼的空值作為空字符串處理。 真值表示空值應當被保留作為空字符串。 默認的假值表示空值會被忽略并將其視作未包括的值。
可選參數 strict_parsing 是一個旗標,指明要如何處理解析錯誤。 如為假值(默認),錯誤會被靜默地忽略。 如為真值,錯誤會引發(fā)
ValueError異常。可選的 encoding 和 errors 形參指定如何將以百分號編碼的序列解碼為 Unicode 字符,即作為
bytes.decode()方法所接受的數據。可選參數 max_num_fields 是要讀取的最大字段數量的。 如果設置,則如果讀取的字段超過 max_num_fields 會引發(fā)
ValueError。可選參數 separator 是用來分隔查詢參數的符號。 默認為
&。使用
urllib.parse.urlencode()函數 (并將doseq形參設為True) 將這樣的字典轉換為查詢字符串。在 3.2 版更改: 增加了 encoding 和 errors 形參。
在 3.8 版更改: 增加了 max_num_fields 形參。
在 3.10 版更改: 增加了 separator 形參,默認值為
&。 Python 在早于 Python 3.10 的版本中允許使用;和&作為查詢參數分隔符。 此設置已被改為只允許單個分隔符鍵,并以&作為默認的分隔符。
- urllib.parse.parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding='utf-8', errors='replace', max_num_fields=None, separator='&')?
解析以字符串參數形式(類型為 application/x-www-form-urlencoded 的數據)給出的查詢字符串。 數據以字段名和字段值對列表的形式返回。
可選參數 keep_blank_values 是一個旗標,指明是否要將以百分號轉碼的空值作為空字符串處理。 真值表示空值應當被保留作為空字符串。 默認的假值表示空值會被忽略并將其視作未包括的值。
可選參數 strict_parsing 是一個旗標,指明要如何處理解析錯誤。 如為假值(默認),錯誤會被靜默地忽略。 如為真值,錯誤會引發(fā)
ValueError異常。可選的 encoding 和 errors 形參指定如何將以百分號編碼的序列解碼為 Unicode 字符,即作為
bytes.decode()方法所接受的數據。可選參數 max_num_fields 是要讀取的最大字段數量的。 如果設置,則如果讀取的字段超過 max_num_fields 會引發(fā)
ValueError。可選參數 separator 是用來分隔查詢參數的符號。 默認為
&。使用
urllib.parse.urlencode()函數將這樣的名值對列表轉換為查詢字符串。在 3.2 版更改: 增加了 encoding 和 errors 形參。
在 3.8 版更改: 增加了 max_num_fields 形參。
在 3.10 版更改: 增加了 separator 形參,默認值為
&。 Python 在早于 Python 3.10 的版本中允許使用;和&作為查詢參數分隔符。 此設置已被改為只允許單個分隔符鍵,并以&作為默認的分隔符。
- urllib.parse.urlunparse(parts)?
根據
urlparse()所返回的元組來構造一個 URL。 parts 參數可以是任何包含六個條目的可迭代對象。 構造的結果可能是略有不同但保持等價的 URL,如果被解析的 URL 原本包含不必要的分隔符(例如,帶有空查詢的?;RFC 已聲明這是等價的)。
- urllib.parse.urlsplit(urlstring, scheme='', allow_fragments=True)?
此函數類似于
urlparse(),但不會拆分來自 URL 的參數。 此函數通常應當在需要允許將參數應用到 URL 的 path 部分的每個分節(jié)的較新的 URL 語法的情況下 (參見 RFC 2396) 被用來代替urlparse()。 需要使用一個拆分函數來拆分路徑分節(jié)和參數。 此函數將返回包含 5 個條目的 named tuple:(addressing scheme, network location, path, query, fragment identifier).
返回值是一個 named tuple,它的條目可以通過索引或作為命名屬性來訪問:
屬性
索引
值
值(如果不存在)
scheme0
URL 協(xié)議說明符
scheme 參數
netloc1
網絡位置部分
空字符串
path2
分層路徑
空字符串
query3
查詢組件
空字符串
fragment4
片段標識符
空字符串
username用戶名
password密碼
hostname主機名(小寫)
port端口號為整數(如果存在)
如果在 URL 中指定了無效的端口,讀取
port屬性將引發(fā)ValueError。 有關結果對象的更多信息請參閱 結構化解析結果 一節(jié)。在
netloc屬性中不匹配的方括號將引發(fā)ValueError。如果
netloc屬性中的字符在 NFKC 規(guī)范化下(如 IDNA 編碼格式所使用的)被分解成/,?,#,@或:則將引發(fā)ValueError。 如果在解析之前 URL 就被分解,則不會引發(fā)錯誤。依據更新 RFC 3986 的 WHATWG spec,ASCII 換行符
\n,\r和制表符\t等字符會從 URL 中被去除。在 3.6 版更改: 超范圍的端口號現在會引發(fā)
ValueError,而不是返回None。在 3.8 版更改: 在 NFKC 規(guī)范化下會影響 netloc 解析的字符現在將引發(fā)
ValueError。在 3.10 版更改: ASCII 換行符和制表符會從 URL 中被去除。
- urllib.parse.urlunsplit(parts)?
將
urlsplit()所返回的元組中的元素合并為一個字符串形式的完整 URL。 parts 參數可以是任何包含五個條目的可迭代對象。 其結果可能是略有不同但保持等價的 URL,如果被解析的 URL 原本包含不必要的分隔符(例如,帶有空查詢的 ?;RFC 已聲明這是等價的)。
- urllib.parse.urljoinbase, url, allow_fragments=True)?
通過合并一個 "基準 URL" (base) 和另一個 URL (url) 來構造一個完整 ("absolute") URL。 在非正式情況下,這將使用基準 URL 的各部分,特別是地址協(xié)議、網絡位置和 (一部分) 路徑來提供相對 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 的主機名和/或協(xié)議將出現在結果中。 例如:>>> urljoin('http://www.cwi.nl/%7Eguido/Python.html', ... '//www.python.org/%7Eguido') 'http://www.python.org/%7Eguido'
如果你不想要那樣的行為,請使用
urlsplit()和urlunsplit()對 url 進行預處理,移除可能存在的 scheme 和 netloc 部分。在 3.5 版更改: 更新行為以匹配 RFC 3986 中定義的語義。
- urllib.parse.urldefrag(url)?
如果 url 包含片段標識符,則返回不帶片段標識符的 url 修改版本。 如果 url 中沒有片段標識符,則返回未經修改的 url 和一個空字符串。
返回值是一個 named tuple,它的條目可以通過索引或作為命名屬性來訪問:
屬性
索引
值
值(如果不存在)
url0
不帶片段的 URL
空字符串
fragment1
片段標識符
空字符串
請參閱 結構化解析結果 一節(jié)了解有關結果對象的更多信息。
在 3.2 版更改: 結果為已構造好的對象而不是一個簡單的 2 元組。-tuple.
- urllib.parse.unwrap(url)?
從已包裝的 URL (即被格式化為
<URL:scheme://host/path>,<scheme://host/path>,URL:scheme://host/path或scheme://host/path的字符串) 中提取 URL。 如果 url 不是一個已包裝的 URL,它將被原樣返回。
解析ASCII編碼字節(jié)?
這些 URL 解析函數最初設計只用于操作字符串。 但在實踐中,它也能夠操作經過正確轉碼和編碼的 ASCII 字節(jié)序列形式的 URL。 相應地,此模塊中的 URL 解析函數既可以操作 str 對象也可以操作 bytes 和 bytearray 對象。
如果傳入 str 數據,結果將只包含 str 數據。 如果傳入 bytes 或 bytearray 數據,則結果也將只包含 bytes 數據。
試圖在單個函數調用中混用 str 數據和 bytes 或 bytearray 數據將導致引發(fā) TypeError,而試圖傳入非 ASCII 字節(jié)值則將引發(fā) UnicodeDecodeError。
為了支持結果對象在 str 和 bytes 之間方便地轉換,所有來自 URL 解析函數的返回值都會提供 encode() 方法 (當結果包含 str 數據) 或 decode() 方法 (當結果包含 bytes 數據)。 這些方法的簽名與 str 和 bytes 的對應方法相匹配 (不同之處在于其默認編碼格式是 'ascii' 而非 'utf-8')。 每個方法會輸出包含相應類型的 bytes 數據 (對于 encode() 方法) 或 str 數據 (對于 decode() 方法) 的值。
對于某些需要在有可能不正確地轉碼的包含非 ASCII 數據的 URL 上進行操作的應用程序來說,在發(fā)起調用 URL 解析方法之前必須自行將字節(jié)串解碼為字符。
在本節(jié)中描述的行為僅適用于 URL 解析函數。 URL 轉碼函數在產生和消耗字節(jié)序列時使用它們自己的規(guī)則,詳情參見單獨 URL 轉碼函數的文檔。
在 3.2 版更改: URL 解析函數現在接受 ASCII 編碼的字節(jié)序列
結構化解析結果?
urlparse(), urlsplit() 和 urldefrag() 函數的結果對象是 tuple 類型的子類。 這些子類中增加了在那些函數的文檔中列出的屬性,之前小節(jié)中描述的編碼和解碼支持,以及一個附加方法:
- urllib.parse.SplitResult.geturl()?
以字符串形式返回原始 URL 的重合并版本。 這可能與原始 URL 有所不同,例如協(xié)議的名稱可能被正規(guī)化為小寫字母、空的組成部分可能被丟棄。 特別地,空的參數、查詢和片段標識符將會被移除。
對于
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)?
用于
urldefrag()結果的實體類,包含有str數據。encode()方法會返回一個DefragResultBytes實例。3.2 新版功能.
- class urllib.parse.ParseResult(scheme, netloc, path, params, query, fragment)?
用于
urlparse()結果的實體類,包含有str數據。encode()方法會返回一個ParseResultBytes實例。
- class urllib.parse.SplitResult(scheme, netloc, path, query, fragment)?
用于
urlsplit()結果的實體類,包含有str數據。encode()方法會返回一個SplitResultBytes實例。
下面的類提供了當在 bytes 或 bytearray 對象上操作時對解析結果的實現:
- class urllib.parse.DefragResultBytes(url, fragment)?
用于
urldefrag()結果的實體類,包含有bytes數據。decode()方法會返回一個DefragResult實例。3.2 新版功能.
- class urllib.parse.ParseResultBytes(scheme, netloc, path, params, query, fragment)?
用于
urlparse()結果的實體類,包含有bytes數據。decode()方法會返回一個ParseResult實例。3.2 新版功能.
- class urllib.parse.SplitResultBytes(scheme, netloc, path, query, fragment)?
用于
urlsplit()結果的實體類,包含有bytes數據。decode()方法會返回一個SplitResult實例。3.2 新版功能.
URL 轉碼?
URL 轉碼函數的功能是接收程序數據并通過對特殊字符進行轉碼并正確編碼非 ASCII 文本來將其轉為可以安全地用作 URL 組成部分的形式。 它們還支持逆轉此操作以便從作為 URL 組成部分的內容中重建原始數據,如果上述的 URL 解析函數還未覆蓋此功能的話。
- urllib.parse.quote(string, safe='/', encoding=None, errors=None)?
使用
%xx轉義符替換 string 中的特殊字符。 字母、數字和'_.-~'等字符一定不會被轉碼。 在默認情況下,此函數只對 URL 的路徑部分進行轉碼。 可選的 safe 形參額外指定不應被轉碼的 ASCII 字符 --- 其默認值為'/'。可選的 encoding 和 errors 形參指明如何處理非 ASCII 字符,與
str.encode()方法所接受的值一樣。 encoding 默認為'utf-8'。 errors 默認為'strict',表示不受支持的字符將引發(fā)UnicodeEncodeError。 如果 string 為bytes則不可提供 encoding 和 errors,否則將引發(fā)TypeError。請注意
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,并且不執(zhí)行從字符串到字節(jié)串的編碼。例如:
quote_from_bytes(b'a&\xef')將產生'a%26%EF'。
- urllib.parse.unquote(string, encoding='utf-8', errors='replace')?
將
%xx轉義符替換為其單字符等價物。 可選的 encoding 和 errors 形參指定如何將以百分號編碼的序列解碼為 Unicode 字符,即bytes.decode()方法所接受的數據。encoding 默認為
'utf-8'。 errors 默認為'replace',表示無效的序列將被替換為占位字符。例如:
unquote('/El%20Ni%C3%B1o/')將產生'/El Ni?o/'。在 3.9 版更改: string 形參支持 bytes 和 str 對象(之前僅支持 str)。
- urllib.parse.unquote_plus(string, encoding='utf-8', errors='replace')?
類似于
unquote(),但還會將加號替換為空格,如反轉碼表單值所要求的。string 必須為
str。例如:
unquote_plus('/El+Ni%C3%B1o/')將產生'/El Ni?o/'。
- urllib.parse.unquote_to_bytes(string)?
將
%xx轉義符替換為其單八位等價物,并返回一個bytes對象。如果它是
str,則 string 中未轉義的非 ASCII 字符會被編碼為 UTF-8 字節(jié)串。例如:
unquote_to_bytes('a%26%EF')y將產生b'a&\xef'。
- urllib.parse.urlencode(query, doseq=False, safe='', encoding=None, errors=None, quote_via=quote_plus)?
將一個包含有
str或bytes對象的映射對象或二元組序列轉換為以百分號編碼的 ASCII 文本字符串。 如果所產生的字符串要被用作urlopen()函數的 POST 操作的 data,則它應當被編碼為字節(jié)串,否則它將導致TypeError。結果字符串是一系列
key=value對,由'&'字符進行分隔,其中 key 和 value 都已使用 quote_via 函數轉碼。 在默認情況下,會使用quote_plus()來轉碼值,這意味著空格會被轉碼為'+'字符而 '/' 字符會被轉碼為%2F,即遵循 GET 請求的標準 (application/x-www-form-urlencoded)。 另一個可以作為 quote_via 傳入的替代函數是quote(),它將把空格轉碼為%20并且不編碼 '/' 字符。 為了最大程序地控制要轉碼的內容,請使用quote并指定 safe 的值。當使用二元組序列作為 query 參數時,每個元組的第一個元素為鍵而第二個元素為值。 值元素本身也可以為一個序列,在那種情況下,如果可選的形參 doseq 的值為
True,則每個鍵的值序列元素生成單個key=value對(以'&'分隔)。 被編碼的字符串中的參數順序將與序列中的形參元素順序相匹配。safe, encoding 和 errors 形參會被傳遞給 quote_via (encoding 和 errors 形參僅在查詢元素為
str時會被傳遞)。為了反向執(zhí)行這個編碼過程,此模塊提供了
parse_qs()和parse_qsl()來將查詢字符串解析為 Python 數據結構。請參考 urllib 示例 來了解如何使用
urllib.parse.urlencode()方法來生成 URL 的查詢字符串或 POST 請求的數據。在 3.2 版更改: 查詢支持字節(jié)和字符串對象。
3.5 新版功能: quote_via 參數.
參見
- WHATWG - URL 現有標準
定義 URL、域名、IP 地址、application/x-www-form-urlencoded 格式及其 API 的工作組。
- RFC 3986 - 統(tǒng)一資源標識符
這是當前的標準 (STD66)。 任何對于 urllib.parse 模塊的修改都必須遵循該標準。 某些偏離也可能會出現,這大都是出于向下兼容的目的以及特定的經常存在于各主要瀏覽器上的實際解析需求。
- RFC 2732 - URL 中的 IPv6 Addresses 地址顯示格式。
這指明了 IPv6 URL 的解析要求。
- RFC 2396 - 統(tǒng)一資源標識符(URI):通用語法
描述統(tǒng)一資源名稱 (URN) 和統(tǒng)一資源定位符 (URL) 通用語義要求的文檔。
- RFC 2368 - mailto URL 模式。
mailto URL 模式的解析要求。
- RFC 1808 - 相對統(tǒng)一資源定位符
這個請求注釋包括聯(lián)結絕對和相對 URL 的規(guī)則,其中包括大量控制邊界情況處理的 "異常示例"。
- RFC 1738 - 統(tǒng)一資源定位符 (URL)
這指明了絕對 URL 的正式語義和句法。