urllib.request --- 用于打開 URL 的可擴(kuò)展庫(kù)?

源碼: Lib/urllib/request.py


urllib.request 模塊定義了適用于在各種復(fù)雜情況下打開 URL(主要為 HTTP)的函數(shù)和類 --- 例如基本認(rèn)證、摘要認(rèn)證、重定向、cookies 及其它。

參見

對(duì)于更高級(jí)別的 HTTP 客戶端接口,建議使用 Requests

urllib.request 模塊定義了以下函數(shù):

urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)?

打開統(tǒng)一資源定位符 url,可以是一個(gè)字符串或一個(gè) Request 對(duì)象。

data 必須是一個(gè)對(duì)象,用于給出要發(fā)送到服務(wù)器的附加數(shù)據(jù),若不需要發(fā)送數(shù)據(jù)則為 None。詳情請(qǐng)參閱 Request 。

urllib.request 模塊采用 HTTP/1.1 協(xié)議,并且在其 HTTP 請(qǐng)求中包含 Connection:close 頭部信息。

timeout 為可選參數(shù),用于指定阻塞操作(如連接嘗試)的超時(shí)時(shí)間,單位為秒。如未指定,將使用全局默認(rèn)超時(shí)參數(shù))。本參數(shù)實(shí)際僅對(duì) HTTP、HTTPS 和 FTP 連接有效。

如果給定了 context 參數(shù),則必須是一個(gè) ssl.SSLContext 實(shí)例,用于描述各種 SSL 參數(shù)。更多詳情請(qǐng)參閱 HTTPSConnection 。

cafilecapath 為可選參數(shù),用于為 HTTPS 請(qǐng)求指定一組受信 CA 證書。cafile 應(yīng)指向包含CA 證書的單個(gè)文件, capath 則應(yīng)指向哈希證書文件的目錄。更多信息可參閱 ssl.SSLContext.load_verify_locations() 。

參數(shù) cadefault 將被忽略。

本函數(shù)總會(huì)返回一個(gè)對(duì)象,該對(duì)象可作為 context manager 使用,帶有 url、headersstatus 屬性。有關(guān)這些屬性的更多詳細(xì)信息,請(qǐng)參閱 urllib.response.addinfourl

對(duì)于 HTTP 和 HTTPS 的 URL 而言,本函數(shù)將返回一個(gè)稍經(jīng)修改的 http.client.HTTPResponse 對(duì)象。除了上述 3 個(gè)新的方法之外,還有 msg 屬性包含了與 reason 屬性相同的信息---服務(wù)器返回的原因描述文字,而不是 HTTPResponse 的文檔所述的響應(yīng)頭部信息。

對(duì)于 FTP、文件、數(shù)據(jù)的URL,以及由傳統(tǒng)的 URLopener  和 FancyURLopener 類處理的請(qǐng)求,本函數(shù)將返回一個(gè) urllib.response.addinfourl 對(duì)象。

協(xié)議發(fā)生錯(cuò)誤時(shí),將會(huì)引發(fā) URLError 。

請(qǐng)注意,如果沒(méi)有處理函數(shù)對(duì)請(qǐng)求進(jìn)行處理,則有可能會(huì)返回 None 。盡管默認(rèn)安裝的全局 OpenerDirector 會(huì)用 UnknownHandler 來(lái)確保不會(huì)發(fā)生這種情況。

此外,如果檢測(cè)到設(shè)置了代理(比如設(shè)置了 http_proxy 之類的環(huán)境變量),默認(rèn)會(huì)安裝 ProxyHandler 并確保通過(guò)代理處理請(qǐng)求。

Python 2.6 以下版本中留存的 urllib.urlopen 函數(shù)已停止使用了; urllib.request.urlopen() 對(duì)應(yīng)于傳統(tǒng)的 urllib2.urlopen 。對(duì)代理服務(wù)的處理是通過(guò)將字典參數(shù)傳給 urllib.urlopen 來(lái)完成的,可以用 ProxyHandler 對(duì)象獲取到代理處理函數(shù)。

默認(rèn)會(huì)觸發(fā)一條 審計(jì)事件 urllib.Request ,參數(shù) fullurl 、 dataheaders 、method 均取自請(qǐng)求對(duì)象。

在 3.2 版更改: 增加了 cafilecapath。

在 3.2 版更改: 只要條件允許(指 ssl.HAS_SNI 為真),現(xiàn)在能夠支持 HTTPS 虛擬主機(jī)。

3.2 新版功能: data 可以是一個(gè)可迭代對(duì)象。

在 3.3 版更改: 增加了 cadefault。

在 3.4.3 版更改: 增加了 context。

在 3.10 版更改: 當(dāng)未給出 context 時(shí),HTTPS 連接現(xiàn)在會(huì)發(fā)送一個(gè)帶有協(xié)議指示器 http/1.1 的 ALPN 擴(kuò)展。 自定義 context 應(yīng)當(dāng)用 set_alpn_protocol() 來(lái)設(shè)置 ALPN 協(xié)議。

3.6 版后已移除: cafile 、 capathcadefault 已廢棄,轉(zhuǎn)而推薦使用 context。請(qǐng)改用 ssl.SSLContext.load_cert_chain() 或讓 ssl.create_default_context() 選取系統(tǒng)信任的 CA 證書。

urllib.request.install_opener(opener)?

安裝一個(gè) OpenerDirector 實(shí)例,作為默認(rèn)的全局打開函數(shù)。僅當(dāng) urlopen 用到該打開函數(shù)時(shí)才需要安裝;否則,只需調(diào)用 OpenerDirector.open() 而不是 urlopen()。代碼不會(huì)檢查是否真的屬于 OpenerDirector 類,所有具備適當(dāng)接口的類都能適用。

urllib.request.build_opener([handler, ...])?

返回一個(gè) OpenerDirector 實(shí)例,以給定順序把處理函數(shù)串聯(lián)起來(lái)。處理函數(shù)可以是 BaseHandler 的實(shí)例,也可以是 BaseHandler 的子類(這時(shí)構(gòu)造函數(shù)必須允許不帶任何參數(shù)的調(diào)用)。以下類的實(shí)例將位于 處理函數(shù) 之前,除非 處理函數(shù) 已包含這些類、其實(shí)例或其子類: ProxyHandler (如果檢測(cè)到代理設(shè)置)、UnknownHandler 、HTTPHandlerHTTPDefaultErrorHandler 、HTTPRedirectHandler 、 FTPHandler 、 FileHandler 、HTTPErrorProcessor 。

若 Python 安裝時(shí)已帶了 SSL 支持(指可以導(dǎo)入 ssl 模塊),則還會(huì)加入 HTTPSHandler 。

A BaseHandler subclass may also change its handler_order attribute to modify its position in the handlers list.

urllib.request.pathname2url(path)?

將路徑名 path 從路徑本地寫法轉(zhuǎn)換為 URL 路徑部分所采用的格式。本函數(shù)不會(huì)生成完整的 URL。返回值將會(huì)用 quote() 函數(shù)加以編碼。

urllib.request.url2pathname(path)?

從百分號(hào)編碼的 URL 中將 path 部分轉(zhuǎn)換為本地路徑的寫法。本函數(shù)不接受完整的 URL,并利用 unquote() 函數(shù)對(duì) path 進(jìn)行解碼。

urllib.request.getproxies()?

This helper function returns a dictionary of scheme to proxy server URL mappings. It scans the environment for variables named <scheme>_proxy, in a case insensitive approach, for all operating systems first, and when it cannot find it, looks for proxy information from System Configuration for macOS and Windows Systems Registry for Windows. If both lowercase and uppercase environment variables exist (and disagree), lowercase is preferred.

備注

如果存在環(huán)境變量 REQUEST_METHOD ,通常表示腳本運(yùn)行于 CGI 環(huán)境中,則環(huán)境變量 HTTP_PROXY (大寫的 _PROXY)將會(huì)被忽略。這是因其可以由客戶端用 HTTP 頭部信息 “Proxy:”注入。若要在 CGI 環(huán)境中使用 HTTP 代理,請(qǐng)顯式使用 `ProxyHandler ,或確保變量名稱為小寫(或至少是 _proxy 后綴)。

提供了以下類:

class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)?

URL 請(qǐng)求對(duì)象的抽象類。

url 應(yīng)為包含合法 URL 的字符串。

data 必須是一個(gè)對(duì)象,用于給定發(fā)往服務(wù)器的附加數(shù)據(jù),若無(wú)需此類數(shù)據(jù)則為 None 。 目前 唯一用到 data 的只有 HTTP 請(qǐng)求。支持的對(duì)象類型包括字節(jié)串、類文件對(duì)象和可遍歷的類字節(jié)串對(duì)象。如果沒(méi)有提供 Content-LengthTransfer-Encoding 頭部字段, HTTPHandler 會(huì)根據(jù) data 的類型設(shè)置這些頭部字段。Content-Length 將用于發(fā)送字節(jié)對(duì)象,而 RFC 7230 第 3.3.1 節(jié)中定義的 Transfer-Encoding: chunked 將用于發(fā)送文件和其他可遍歷對(duì)象。

對(duì)于 HTTP POST 請(qǐng)求方法而言,data 應(yīng)該是標(biāo)準(zhǔn) application/x-www-form-urlencoded 格式的緩沖區(qū)。 urllib.parse.urlencode() 函數(shù)的參數(shù)為映射對(duì)象或二元組序列,并返回一個(gè)該編碼格式的 ASCII 字符串。在用作 data 參數(shù)之前,應(yīng)將其編碼為字節(jié)串。

headers should be a dictionary, and will be treated as if add_header() was called with each key and value as arguments. This is often used to "spoof" the User-Agent header value, which is used by a browser to identify itself -- some HTTP servers only allow requests coming from common browsers as opposed to scripts. For example, Mozilla Firefox may identify itself as "Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11", while urllib's default user agent string is "Python-urllib/2.6" (on Python 2.6). All header keys are sent in camel case.

如果給出了 data 參數(shù),則應(yīng)當(dāng)包含合適的 Content-Type 頭部信息。若未提供且 data 不是 None,則會(huì)把 Content-Type: application/x-www-form-urlencoded 加入作為默認(rèn)值。

接下來(lái)的兩個(gè)參數(shù),只對(duì)第三方 HTTP cookie 的處理才有用:

origin_req_host 應(yīng)為發(fā)起初始會(huì)話的請(qǐng)求主機(jī),定義參見 RFC 2965 。默認(rèn)指為``http.cookiejar.request_host(self)`` 。這是用戶發(fā)起初始請(qǐng)求的主機(jī)名或 IP 地址。假設(shè)請(qǐng)求是針對(duì) HTML 文檔中的圖片數(shù)據(jù)發(fā)起的,則本屬性應(yīng)為對(duì)包含圖像的頁(yè)面發(fā)起請(qǐng)求的主機(jī)。

unverifiable 應(yīng)該標(biāo)示出請(qǐng)求是否無(wú)法驗(yàn)證,定義參見 RFC 2965 。默認(rèn)值為 False 。所謂無(wú)法驗(yàn)證的請(qǐng)求,是指用戶沒(méi)有機(jī)會(huì)對(duì)請(qǐng)求的 URL 做驗(yàn)證。例如,如果請(qǐng)求是針對(duì) HTML 文檔中的圖像,用戶沒(méi)有機(jī)會(huì)去許可能自動(dòng)讀取圖像,則本參數(shù)應(yīng)為 True。

method 應(yīng)為字符串,標(biāo)示要采用的 HTTP 請(qǐng)求方法(例如 'HEAD' )。如果給出本參數(shù),其值會(huì)存儲(chǔ)在 method 屬性中,并由 get_method() 使用。如果 data 為``None`` 則默認(rèn)值為 'GET' ,否則為 'POST'。子類可以設(shè)置 method 屬性來(lái)標(biāo)示不同的默認(rèn)請(qǐng)求方法。

備注

如果 data 對(duì)象無(wú)法分多次傳遞其內(nèi)容(比如文件或只能生成一次內(nèi)容的可迭代對(duì)象)并且由于 HTTP 重定向或身份驗(yàn)證而發(fā)生請(qǐng)求重試行為,則該請(qǐng)求不會(huì)正常工作。 data 是緊挨著頭部信息發(fā)送給 HTTP 服務(wù)器的?,F(xiàn)有庫(kù)不支持 HTTP 100-continue 的征詢。

在 3.3 版更改: Request 類增加了 Request.method 參數(shù)。

在 3.4 版更改: 默認(rèn) Request.method 可以在類中標(biāo)明。

在 3.6 版更改: 如果給出了 Content-Length ,且 data 既不為 None 也不是字節(jié)串對(duì)象,則不會(huì)觸發(fā)錯(cuò)誤。而會(huì)退而求其次采用分塊傳輸?shù)木幋a格式。

class urllib.request.OpenerDirector?

OpenerDirector 類通過(guò)串接在一起的 BaseHandler 打開 URL,并負(fù)責(zé)管理 handler 鏈及從錯(cuò)誤中恢復(fù)。

class urllib.request.BaseHandler?

這是所有已注冊(cè) handler 的基類,只做了簡(jiǎn)單的注冊(cè)機(jī)制。

class urllib.request.HTTPDefaultErrorHandler?

為 HTTP 錯(cuò)誤響應(yīng)定義的默認(rèn) handler,所有出錯(cuò)響應(yīng)都會(huì)轉(zhuǎn)為 HTTPError 異常。

class urllib.request.HTTPRedirectHandler?

一個(gè)用于處理重定向的類。

class urllib.request.HTTPCookieProcessor(cookiejar=None)?

一個(gè)用于處理 HTTP Cookies 的類。

class urllib.request.ProxyHandler(proxies=None)?

Cause requests to go through a proxy. If proxies is given, it must be a dictionary mapping protocol names to URLs of proxies. The default is to read the list of proxies from the environment variables <protocol>_proxy. If no proxy environment variables are set, then in a Windows environment proxy settings are obtained from the registry's Internet Settings section, and in a macOS environment proxy information is retrieved from the System Configuration Framework.

若要禁用自動(dòng)檢測(cè)出來(lái)的代理,請(qǐng)傳入空的字典對(duì)象。

環(huán)境變量 no_proxy 可用于指定不必通過(guò)代理訪問(wèn)的主機(jī);應(yīng)為逗號(hào)分隔的主機(jī)名后綴列表,可加上 :port ,例如 cern.ch,ncsa.uiuc.edu,some.host:8080 。

備注

如果設(shè)置了 REQUEST_METHOD 變量,則會(huì)忽略 HTTP_PROXY ;參閱 getproxies() 文檔。

class urllib.request.HTTPPasswordMgr?

維護(hù) (realm, uri) -> (user, password) 映射數(shù)據(jù)庫(kù)。

class urllib.request.HTTPPasswordMgrWithDefaultRealm?

維護(hù) (realm, uri) -> (user, password) 映射數(shù)據(jù)庫(kù)。realm 為 None 視作全匹配,若沒(méi)有其他合適的安全區(qū)域就會(huì)檢索它。

class urllib.request.HTTPPasswordMgrWithPriorAuth?

HTTPPasswordMgrWithDefaultRealm 的一個(gè)變體,也帶有 uri -> is_authenticated 映射數(shù)據(jù)庫(kù)??杀?BasicAuth 處理函數(shù)用于確定立即發(fā)送身份認(rèn)證憑據(jù)的時(shí)機(jī),而不是先等待 401 響應(yīng)。

3.5 新版功能.

class urllib.request.AbstractBasicAuthHandler(password_mgr=None)?

這是一個(gè)幫助完成 HTTP 身份認(rèn)證的混合類,對(duì)遠(yuǎn)程主機(jī)和代理都適用。參數(shù) password_mgr 應(yīng)與 HTTPPasswordMgr 兼容;關(guān)于必須支持哪些接口,請(qǐng)參閱 HTTPPasswordMgr 對(duì)象 對(duì)象的章節(jié)。如果 password_mgr 還提供 is_authenticatedupdate_authenticated 方法(請(qǐng)參閱 HTTPPasswordMgrWithPriorAuth 對(duì)象 對(duì)象),則 handler 將對(duì)給定 URI 用到 is_authenticated 的結(jié)果,來(lái)確定是否隨請(qǐng)求發(fā)送身份認(rèn)證憑據(jù)。如果該 URI 的 is_authenticated 返回 True,則發(fā)送憑據(jù)。如果 is_authenticatedFalse ,則不發(fā)送憑據(jù),然后若收到 401 響應(yīng),則使用身份認(rèn)證憑據(jù)重新發(fā)送請(qǐng)求。如果身份認(rèn)證成功,則調(diào)用 update_authenticated 設(shè)置該 URI 的 is_authenticatedTrue,這樣后續(xù)對(duì)該 URI 或其所有父 URI 的請(qǐng)求將自動(dòng)包含該身份認(rèn)證憑據(jù)。

3.5 新版功能: 增加了對(duì) is_authenticated 的支持。

class urllib.request.HTTPBasicAuthHandler(password_mgr=None)?

處理遠(yuǎn)程主機(jī)的身份認(rèn)證。 password_mgr 應(yīng)與 HTTPPasswordMgr 兼容;有關(guān)哪些接口是必須支持的,請(qǐng)參閱 HTTPPasswordMgr 對(duì)象 章節(jié)。如果給出錯(cuò)誤的身份認(rèn)證方式, HTTPBasicAuthHandler 將會(huì)觸發(fā) ValueError 。

class urllib.request.ProxyBasicAuthHandler(password_mgr=None)?

處理有代理服務(wù)時(shí)的身份認(rèn)證。 password_mgr 應(yīng)與 HTTPPasswordMgr 兼容;有關(guān)哪些接口是必須支持的,請(qǐng)參閱 HTTPPasswordMgr 對(duì)象 章節(jié)。

class urllib.request.AbstractDigestAuthHandler(password_mgr=None)?

這是一個(gè)幫助完成 HTTP 身份認(rèn)證的混合類,對(duì)遠(yuǎn)程主機(jī)和代理都適用。參數(shù) password_mgr 應(yīng)與 HTTPPasswordMgr 兼容;關(guān)于必須支持哪些接口,請(qǐng)參閱 HTTPPasswordMgr 對(duì)象 的章節(jié)。

class urllib.request.HTTPDigestAuthHandler(password_mgr=None)?

處理遠(yuǎn)程主機(jī)的身份認(rèn)證。 password_mgr 應(yīng)與 HTTPPasswordMgr 兼容;有關(guān)哪些接口是必須支持的,請(qǐng)參閱 HTTPPasswordMgr 對(duì)象 章節(jié)。如果同時(shí)添加了 digest 身份認(rèn)證 handler 和basic 身份認(rèn)證 handler,則會(huì)首先嘗試 digest 身份認(rèn)證。如果 digest 身份認(rèn)證再返回 40x 響應(yīng),會(huì)再發(fā)送到 basic 身份驗(yàn)證 handler 進(jìn)行處理。如果給出 Digest 和 Basic 之外的身份認(rèn)證方式, 本 handler 方法將會(huì)觸發(fā) ValueError

在 3.3 版更改: 碰到不支持的認(rèn)證方式時(shí),將會(huì)觸發(fā) ValueError 。

class urllib.request.ProxyDigestAuthHandler(password_mgr=None)?

處理有代理服務(wù)時(shí)的身份認(rèn)證。 password_mgr 應(yīng)與 HTTPPasswordMgr 兼容;有關(guān)哪些接口是必須支持的,請(qǐng)參閱 HTTPPasswordMgr 對(duì)象 章節(jié)。

class urllib.request.HTTPHandler?

用于打開 HTTP URL 的 handler 類。

class urllib.request.HTTPSHandler(debuglevel=0, context=None, check_hostname=None)?

用于打開 HTTPS URL 的 handler 類。contextcheck_hostname 的含義與 http.client.HTTPSConnection 的一樣。

在 3.2 版更改: 添加 contextcheck_hostname 參數(shù)。

class urllib.request.FileHandler?

打開本地文件。

class urllib.request.DataHandler?

打開數(shù)據(jù) URL。

3.4 新版功能.

class urllib.request.FTPHandler?

打開 FTP URL。

class urllib.request.CacheFTPHandler?

打開 FTP URL,并將打開的 FTP 連接存入緩存,以便最大程度減少延遲。

class urllib.request.UnknownHandler?

處理所有未知類型 URL 的兜底類。

class urllib.request.HTTPErrorProcessor?

處理出錯(cuò)的 HTTP 響應(yīng)。

Request 對(duì)象?

以下方法介紹了 Request 的公開接口,因此子類可以覆蓋所有這些方法。這里還定義了幾個(gè)公開屬性,客戶端可以利用這些屬性了解經(jīng)過(guò)解析的請(qǐng)求。

Request.full_url?

傳給構(gòu)造函數(shù)的原始 URL。

在 3.4 版更改.

Request.full_url 是一個(gè)帶有 setter、getter 和 deleter 的屬性。讀取 full_url 屬性將會(huì)返回附帶片段(fragment)的初始請(qǐng)求 URL。

Request.type?

URI 方式。

Request.host?

URI 權(quán)限,通常是整個(gè)主機(jī),但也有可能帶有冒號(hào)分隔的端口號(hào)。

Request.origin_req_host?

請(qǐng)求的原始主機(jī),不含端口。

Request.selector?

URI 路徑。若 Request 使用代理,selector 將會(huì)是傳給代理的完整 URL。

Request.data?

請(qǐng)求的數(shù)據(jù)體,未給出則為 None 。

在 3.4 版更改: 現(xiàn)在如果修改 Request.data 的值,則會(huì)刪除之前設(shè)置或計(jì)算過(guò)的“Content-Length”頭部信息。

Request.unverifiable?

布爾值,標(biāo)識(shí)本請(qǐng)求是否屬于 RFC 2965 中定義的無(wú)法驗(yàn)證的情況。

Request.method?

要采用的 HTTP 請(qǐng)求方法。默認(rèn)為 None,表示 get_method() 將對(duì)方法進(jìn)行正常處理。設(shè)置本值可以覆蓋 get_method() 中的默認(rèn)處理過(guò)程,設(shè)置方式可以是在 Request 的子類中給出默認(rèn)值,也可以通過(guò) method 參數(shù)給 Request 構(gòu)造函數(shù)傳入一個(gè)值。

3.3 新版功能.

在 3.4 版更改: 現(xiàn)在可以在子類中設(shè)置默認(rèn)值;而之前只能通過(guò)構(gòu)造函數(shù)的實(shí)參進(jìn)行設(shè)置。

Request.get_method()?

返回表示 HTTP 請(qǐng)求方法的字符串。如果 Request.method 不為 None ,則返回其值。否則若 Request.data 為 則返回 'GET',不為 None 則返回 'POST' 。只對(duì) HTTP 請(qǐng)求有效。

在 3.3 版更改: 現(xiàn)在 get_method 會(huì)兼顧 Request.method 的值。

Request.add_header(key, val)?

Add another header to the request. Headers are currently ignored by all handlers except HTTP handlers, where they are added to the list of headers sent to the server. Note that there cannot be more than one header with the same name, and later calls will overwrite previous calls in case the key collides. Currently, this is no loss of HTTP functionality, since all headers which have meaning when used more than once have a (header-specific) way of gaining the same functionality using only one header. Note that headers added using this method are also added to redirected requests.

Request.add_unredirected_header(key, header)?

添加一項(xiàng)不會(huì)被加入重定向請(qǐng)求的頭部信息。

Request.has_header(header)?

返回本實(shí)例是否帶有命名頭部信息(對(duì)常規(guī)數(shù)據(jù)和非重定向數(shù)據(jù)都會(huì)檢測(cè))。

Request.remove_header(header)?

從本請(qǐng)求實(shí)例中移除指定命名的頭部信息(對(duì)常規(guī)數(shù)據(jù)和非重定向數(shù)據(jù)都會(huì)檢測(cè))。

3.4 新版功能.

Request.get_full_url()?

返回構(gòu)造器中給定的 URL。

在 3.4 版更改.

返回 Request.full_url

Request.set_proxy(host, type)?

連接代理服務(wù)器,為當(dāng)前請(qǐng)求做準(zhǔn)備。 hosttype 將會(huì)取代本實(shí)例中的對(duì)應(yīng)值,selector 將會(huì)是構(gòu)造函數(shù)中給出的初始 URL。

Request.get_header(header_name, default=None)?

返回給定頭部信息的數(shù)據(jù)。如果該頭部信息不存在,返回默認(rèn)值。

Request.header_items()?

返回頭部信息,形式為(名稱, 數(shù)據(jù))的元組列表。

在 3.4 版更改: 自 3.3 起已棄用的下列方法已被刪除:add_data、has_data、get_data、get_type、get_host、get_selector、get_origin_req_host 和 is_unverifiable 。

OpenerDirector 對(duì)象?

OpenerDirector 實(shí)例有以下方法:

OpenerDirector.add_handler(handler)?

handler 應(yīng)為 BaseHandler 的實(shí)例。將檢索以下類型的方法,并將其添加到對(duì)應(yīng)的處理鏈中(注意 HTTP 錯(cuò)誤是特殊情況)。請(qǐng)注意,下文中的 protocol 應(yīng)替換為要處理的實(shí)際協(xié)議,例如 http_response() 將是 HTTP 協(xié)議響應(yīng)處理函數(shù)。并且 type 也應(yīng)替換為實(shí)際的 HTTP 代碼,例如 http_error_404() 將處理 HTTP 404 錯(cuò)誤。

  • <protocol>_open() — 表明該 handler 知道如何打開 protocol 協(xié)議的URL。

    更多信息請(qǐng)參閱 BaseHandler.<protocol>_open() 。

  • http_error_<type>() — 表明該 handler 知道如何處理代碼為 type 的 HTTP 錯(cuò)誤。

    更多信息請(qǐng)參閱 BaseHandler.http_error_<nnn>() 。

  • <protocol>_error() — 表明該 handler 知道如何處理來(lái)自協(xié)議為 protocol (非http)的錯(cuò)誤。

  • <protocol>_request() — 表明該 handler 知道如何預(yù)處理協(xié)議為 protocol 的請(qǐng)求。

    更多信息請(qǐng)參閱 BaseHandler.<protocol>_request() 。

  • <protocol>_response() — 表明該 handler 知道如何后處理協(xié)議為 protocol 的響應(yīng)。

    更多信息請(qǐng)參閱 BaseHandler.<protocol>_response() 。

OpenerDirector.open(url, data=None[, timeout])?

Open the given url (which can be a request object or a string), optionally passing the given data. Arguments, return values and exceptions raised are the same as those of urlopen() (which simply calls the open() method on the currently installed global OpenerDirector). The optional timeout parameter specifies a timeout in seconds for blocking operations like the connection attempt (if not specified, the global default timeout setting will be used). The timeout feature actually works only for HTTP, HTTPS and FTP connections.

OpenerDirector.error(proto, *args)?

處理給定協(xié)議的錯(cuò)誤。將用給定的參數(shù)(協(xié)議相關(guān))調(diào)用已注冊(cè)的給定協(xié)議的錯(cuò)誤處理程序。HTTP 協(xié)議是特殊情況,采用 HTTP 響應(yīng)碼來(lái)確定具體的錯(cuò)誤處理程序;請(qǐng)參考 handler 類的 http_error_<type>() 方法。

返回值和異常均與 urlopen() 相同。

OpenerDirector 對(duì)象分 3 個(gè)階段打開 URL:

每個(gè)階段中調(diào)用這些方法的次序取決于 handler 實(shí)例的順序。

  1. 每個(gè)具有 _request() 這類方法的 handler 都會(huì)調(diào)用本方法對(duì)請(qǐng)求進(jìn)行預(yù)處理。

  2. 調(diào)用具有 _open() 這類方法的 handler 來(lái)處理請(qǐng)求。當(dāng) handler 返回非None 值(即響應(yīng))或引發(fā)異常(通常是 URLError)時(shí),本階段結(jié)束。本階段能夠傳播異常。

    事實(shí)上,以上算法首先會(huì)嘗試名為 default_open() 的方法。 如果這些方法全都返回 None,則會(huì)對(duì)名為 <protocol>_open() 的方法重復(fù)此算法。 如果這些方法也全都返回 None,則會(huì)繼續(xù)對(duì)名為 unknown_open() 的方法重復(fù)此算法。

    請(qǐng)注意,這些方法的代碼可能會(huì)調(diào)用 OpenerDirector 父實(shí)例的 open()error() 方法。

  3. 每個(gè)具有 _response() 這類方法的 handler 都會(huì)調(diào)用這些方法,以對(duì)響應(yīng)進(jìn)行后處理。

BaseHandler 對(duì)象?

BaseHandler 對(duì)象提供了一些直接可用的方法,以及其他一些可供派生類使用的方法。以下是可供直接使用的方法:

BaseHandler.add_parent(director)?

將 director 加為父 OpenerDirector。

BaseHandler.close()?

移除所有父 OpenerDirector。

以下屬性和方法僅供 BaseHandler 的子類使用:

備注

以下約定已被采納:定義 <protocol>_request()<protocol>_response() 方法的子類應(yīng)命名為 *Processor;所有其他子類都應(yīng)命名為 *Handler

BaseHandler.parent?

一個(gè)可用的 OpenerDirector,可用于以其他協(xié)議打開 URI,或處理錯(cuò)誤。

BaseHandler.default_open(req)?

本方法在 BaseHandler 予定義,但其子類若要捕獲所有 URL 則應(yīng)進(jìn)行定義。

This method, if implemented, will be called by the parent OpenerDirector. It should return a file-like object as described in the return value of the open() method of OpenerDirector, or None. It should raise URLError, unless a truly exceptional thing happens (for example, MemoryError should not be mapped to URLError).

本方法將會(huì)在所有協(xié)議的 open 方法之前被調(diào)用。

BaseHandler.<protocol>_open(req)

本方法在 BaseHandler 予定義,但其子類若要處理給定協(xié)議的 URL 則應(yīng)進(jìn)行定義。

若定義了本方法,將會(huì)被父 OpenerDirector 對(duì)象調(diào)用。返回值和 default_open() 的一樣。

BaseHandler.unknown_open(req)?

本方法在 BaseHandler 予定義,但其子類若要捕獲并打開所有未注冊(cè) handler 的 URL,則應(yīng)進(jìn)行定義。

若實(shí)現(xiàn)了本方法,將會(huì)被 parent 屬性指向的父 OpenerDirector 調(diào)用。返回值和 default_open() 的一樣。

BaseHandler.http_error_default(req, fp, code, msg, hdrs)?

本方法在 BaseHandler 予定義,但其子類若要為所有未定義 handler 的 HTTP 錯(cuò)誤提供一個(gè)兜底方法,則應(yīng)進(jìn)行重寫。OpenerDirector 會(huì)自動(dòng)調(diào)用本方法,獲取錯(cuò)誤信息,而通常在其他時(shí)候不應(yīng)去調(diào)用。

req 會(huì)是一個(gè) Request 對(duì)象,fp 是一個(gè)帶有 HTTP 錯(cuò)誤體的文件類對(duì)象,code 是三位數(shù)的錯(cuò)誤碼,msg 是供用戶閱讀的解釋信息,hdrs 則是一個(gè)包含出錯(cuò)頭部信息的字典對(duì)象。

返回值和觸發(fā)的異常應(yīng)與 urlopen() 的相同。

BaseHandler.http_error_<nnn>(req, fp, code, msg, hdrs)

nnn 應(yīng)為三位數(shù)的 HTTP 錯(cuò)誤碼。本方法在 BaseHandler 中也未予定義,但當(dāng)子類的實(shí)例發(fā)生代碼為 nnn 的 HTTP 錯(cuò)誤時(shí),若方法存在則會(huì)被調(diào)用。

子類應(yīng)該重寫本方法,以便能處理相應(yīng)的 HTTP 錯(cuò)誤。

參數(shù)、返回值和觸發(fā)的異常應(yīng)與 http_error_default() 相同。

BaseHandler.<protocol>_request(req)

本方法在 BaseHandler 予定義,但其子類若要對(duì)給定協(xié)議的請(qǐng)求進(jìn)行預(yù)處理,則應(yīng)進(jìn)行定義。

若實(shí)現(xiàn)了本方法,將會(huì)被父 OpenerDirector 調(diào)用。req 將為 Request 對(duì)象。返回值應(yīng)為 Request 對(duì)象。

BaseHandler.<protocol>_response(req, response)

本方法在 BaseHandler 予定義,但其子類若要對(duì)給定協(xié)議的請(qǐng)求進(jìn)行后處理,則應(yīng)進(jìn)行定義。

若實(shí)現(xiàn)了本方法,將會(huì)被父 OpenerDirector 調(diào)用。req 將為 Request 對(duì)象。response 應(yīng)實(shí)現(xiàn)與 urlopen() 返回值相同的接口。返回值應(yīng)實(shí)現(xiàn)與 urlopen() 返回值相同的接口。

HTTPRedirectHandler 對(duì)象?

備注

某些 HTTP 重定向操作需要本模塊的客戶端代碼提供的功能。這時(shí)會(huì)觸發(fā) HTTPError。有關(guān)各種重定向代碼的確切含義,請(qǐng)參閱 RFC 2616 。

如果給到 HTTPRedirectHandler 的重定向 URL 不是 HTTP、HTTPS 或 FTP URL,則出于安全考慮將觸發(fā) HTTPError 異常。

HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)?

返回 RequestNone 對(duì)象作為重定向行為的響應(yīng)。當(dāng)服務(wù)器接收到重定向請(qǐng)求時(shí), http_error_30*() 方法的默認(rèn)實(shí)現(xiàn)代碼將會(huì)調(diào)用本方法。如果確實(shí)應(yīng)該發(fā)生重定向,則返回一個(gè)新的 Request 對(duì)象,使得 http_error_30*() 能重定向至 newurl。否則,若沒(méi)有 handler 會(huì)處理此 URL,則會(huì)引發(fā) HTTPError;或者本方法不能處理但或許會(huì)有其他 handler 會(huì)處理,則返回 None 。

備注

本方法的默認(rèn)實(shí)現(xiàn)代碼并未嚴(yán)格遵循 RFC 2616,即 POST 請(qǐng)求的 301 和 302 響應(yīng)不得在未經(jīng)用戶確認(rèn)的情況下自動(dòng)進(jìn)行重定向?,F(xiàn)實(shí)情況下,瀏覽器確實(shí)允許自動(dòng)重定向這些響應(yīng),將 POST 更改為 GET ,于是默認(rèn)實(shí)現(xiàn)代碼就復(fù)現(xiàn)了這種處理方式。

HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)?

重定向到 Location:URI: URL。 當(dāng)?shù)玫?HTTP 'moved permanently' 響應(yīng)時(shí),本方法會(huì)被父級(jí) OpenerDirector 調(diào)用。

HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)?

http_error_301() 相同,不過(guò)是發(fā)生“found”響應(yīng)時(shí)的調(diào)用。

HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)?

http_error_301() 相同,不過(guò)是發(fā)生“see other”響應(yīng)時(shí)的調(diào)用。

HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)?

The same as http_error_301(), but called for the 'temporary redirect' response. It does not allow changing the request method from POST to GET.

HTTPRedirectHandler.http_error_308(req, fp, code, msg, hdrs)?

The same as http_error_301(), but called for the 'permanent redirect' response. It does not allow changing the request method from POST to GET.

3.11 新版功能.

HTTPCookieProcessor 對(duì)象?

HTTPCookieProcessor 的實(shí)例具備一個(gè)屬性:

HTTPCookieProcessor.cookiejar?

cookie 存放在 http.cookiejar.CookieJar 中。

ProxyHandler 對(duì)象?

ProxyHandler.<protocol>_open(request)

ProxyHandler 將為每種 protocol 準(zhǔn)備一個(gè) _open() 方法,在構(gòu)造函數(shù)給出的 proxies 字典中包含對(duì)應(yīng)的代理服務(wù)器信息。通過(guò)調(diào)用 request.set_proxy(),本方法將把請(qǐng)求轉(zhuǎn)為通過(guò)代理服務(wù)器,并會(huì)調(diào)用 handler 鏈中的下一個(gè) handler 來(lái)完成對(duì)應(yīng)的協(xié)議處理。

HTTPPasswordMgr 對(duì)象?

以下方法 HTTPPasswordMgrHTTPPasswordMgrWithDefaultRealm 對(duì)象均有提供。

HTTPPasswordMgr.add_password(realm, uri, user, passwd)?

uri 可以是單個(gè) URI,也可以是 URI 列表。realm、userpasswd 必須是字符串。這使得在為 realm 和超級(jí) URI 進(jìn)行身份認(rèn)證時(shí),(user, passwd) 可用作認(rèn)證令牌。

HTTPPasswordMgr.find_user_password(realm, authuri)?

為給定 realm 和 URI 獲取用戶名和密碼。如果沒(méi)有匹配的用戶名和密碼,本方法將會(huì)返回 (None, None) 。

對(duì)于 HTTPPasswordMgrWithDefaultRealm 對(duì)象,如果給定 realm 沒(méi)有匹配的用戶名和密碼,將搜索 realm None。

HTTPPasswordMgrWithPriorAuth 對(duì)象?

這是 HTTPPasswordMgrWithDefaultRealm 的擴(kuò)展,以便對(duì)那些需要一直發(fā)送認(rèn)證憑證的 URI 進(jìn)行跟蹤。

HTTPPasswordMgrWithPriorAuth.add_password(realm, uri, user, passwd, is_authenticated=False)?

realmuri、user、passwd 的含義與 HTTPPasswordMgr.add_password() 的相同。is_authenticated 為給定 URI 或 URI 列表設(shè)置 is_authenticated 標(biāo)志的初始值。如果 is_authenticated 設(shè)為 True ,則會(huì)忽略 realm。

HTTPPasswordMgrWithPriorAuth.find_user_password(realm, authuri)?

HTTPPasswordMgrWithDefaultRealm 對(duì)象的相同。

HTTPPasswordMgrWithPriorAuth.update_authenticated(self, uri, is_authenticated=False)?

更新給定 uri 或 URI 列表的 is_authenticated 標(biāo)志。

HTTPPasswordMgrWithPriorAuth.is_authenticated(self, authuri)?

返回給定 URI is_authenticated 標(biāo)志的當(dāng)前狀態(tài)。

AbstractBasicAuthHandler 對(duì)象?

AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)?

通過(guò)獲取用戶名和密碼并重新嘗試請(qǐng)求,以處理身份認(rèn)證請(qǐng)求。 authreq 應(yīng)該是請(qǐng)求中包含 realm 的頭部信息名稱,host 指定了需要進(jìn)行身份認(rèn)證的 URL 和路徑,req 應(yīng)為 (已失敗的) Request 對(duì)象 , headers 應(yīng)該是出錯(cuò)的頭部信息。

host 要么是一個(gè)認(rèn)證信息(例如 "python.org" ),要么是一個(gè)包含認(rèn)證信息的 URL(如``"http://python.org/"`` )。 不論是哪種格式,認(rèn)證信息中都不能包含用戶信息(因此,"python.org""python.org:80" 沒(méi)問(wèn)題,而 "joe:password@python.org" 則不行)。

HTTPBasicAuthHandler 對(duì)象?

HTTPBasicAuthHandler.http_error_401(req, fp, code, msg, hdrs)?

如果可用的話,請(qǐng)用身份認(rèn)證信息重試請(qǐng)求。

ProxyBasicAuthHandler 對(duì)象?

ProxyBasicAuthHandler.http_error_407(req, fp, code, msg, hdrs)?

如果可用的話,請(qǐng)用身份認(rèn)證信息重試請(qǐng)求。

AbstractDigestAuthHandler 對(duì)象?

AbstractDigestAuthHandler.http_error_auth_reqed(authreq, host, req, headers)?

authreq 應(yīng)為請(qǐng)求中有關(guān) realm 的頭部信息名稱,host 應(yīng)為需要進(jìn)行身份認(rèn)證的主機(jī),req 應(yīng)為(已失敗的) Request 對(duì)象, headers 則應(yīng)為出錯(cuò)的頭部信息。

HTTPDigestAuthHandler 對(duì)象?

HTTPDigestAuthHandler.http_error_401(req, fp, code, msg, hdrs)?

如果可用的話,請(qǐng)用身份認(rèn)證信息重試請(qǐng)求。

ProxyDigestAuthHandler 對(duì)象?

ProxyDigestAuthHandler.http_error_407(req, fp, code, msg, hdrs)?

如果可用的話,請(qǐng)用身份認(rèn)證信息重試請(qǐng)求。

HTTPHandler 對(duì)象?

HTTPHandler.http_open(req)?

發(fā)送 HTTP 請(qǐng)求,根據(jù) req.has_data() 的結(jié)果,可能是 GET 或 POST 格式。

HTTPSHandler 對(duì)象?

HTTPSHandler.https_open(req)?

發(fā)送 HTTPS 請(qǐng)求,根據(jù) req.has_data() 的結(jié)果,可能是 GET 或 POST 格式。

FileHandler 對(duì)象?

FileHandler.file_open(req)?

若無(wú)主機(jī)名或主機(jī)名為 'localhost' ,則打開本地文件。

在 3.2 版更改: 本方法僅適用于本地主機(jī)名。如果給出的是遠(yuǎn)程主機(jī)名,將會(huì)觸發(fā) URLError 。

DataHandler 對(duì)象?

DataHandler.data_open(req)?

讀取內(nèi)含數(shù)據(jù)的 URL。這種 URL 本身包含了經(jīng)過(guò)編碼的數(shù)據(jù)。 RFC 2397 中給出了數(shù)據(jù) URL 的語(yǔ)法定義。目前的代碼庫(kù)將忽略經(jīng)過(guò) base64 編碼的數(shù)據(jù) URL 中的空白符,因此 URL 可以放入任何源碼文件中。如果數(shù)據(jù) URL 的 base64 編碼尾部缺少填充,即使某些瀏覽器不介意,但目前的代碼庫(kù)仍會(huì)引發(fā) ValueError。

FTPHandler 對(duì)象?

FTPHandler.ftp_open(req)?

打開由 req 給出的 FTP 文件。登錄時(shí)的用戶名和密碼總是為空。

CacheFTPHandler 對(duì)象?

CacheFTPHandler 對(duì)象即為加入以下方法的 FTPHandler 對(duì)象:

CacheFTPHandler.setTimeout(t)?

設(shè)置連接超時(shí)為 t 秒。

CacheFTPHandler.setMaxConns(m)?

設(shè)置已緩存的最大連接數(shù)為 m 。

UnknownHandler 對(duì)象?

UnknownHandler.unknown_open()?

觸發(fā) URLError 異常。

HTTPErrorProcessor 對(duì)象?

HTTPErrorProcessor.http_response(request, response)?

處理出錯(cuò)的 HTTP 響應(yīng)。

對(duì)于 200 錯(cuò)誤碼,響應(yīng)對(duì)象應(yīng)立即返回。

對(duì)于 200 以外的錯(cuò)誤碼,只通過(guò) OpenerDirector.error() 將任務(wù)傳給 handler 的 http_error_<type>() 方法。如果最終沒(méi)有 handler 處理錯(cuò)誤, HTTPDefaultErrorHandler 將觸發(fā) HTTPError

HTTPErrorProcessor.https_response(request, response)?

HTTPS 出錯(cuò)響應(yīng)的處理。

http_response() 方法相同。

例子?

如何利用 urllib 包獲取網(wǎng)絡(luò)資源 中給出了更多的示例。

以下示例將讀取 python.org 主頁(yè)并顯示前 300 個(gè)字節(jié)的內(nèi)容:

>>>
>>> import urllib.request
>>> with urllib.request.urlopen('http://www.python.org/') as f:
...     print(f.read(300))
...
b'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n\n\n<html
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n\n<head>\n
<meta http-equiv="content-type" content="text/html; charset=utf-8" />\n
<title>Python Programming '

請(qǐng)注意,urlopen 將返回字節(jié)對(duì)象。這是因?yàn)?urlopen 無(wú)法自動(dòng)確定由 HTTP 服務(wù)器收到的字節(jié)流的編碼。通常,只要能確定或猜出編碼格式,就應(yīng)將返回的字節(jié)對(duì)象解碼為字符串。

下述 W3C 文檔 https://www.w3.org/International/O-charset列出了可用于指明(X)HTML 或 XML 文檔編碼信息的多種方案。

python.org 網(wǎng)站已在 meta 標(biāo)簽中指明,采用的是 utf-8 編碼,因此這里將用同樣的格式對(duì)字節(jié)串進(jìn)行解碼。

>>>
>>> with urllib.request.urlopen('http://www.python.org/') as f:
...     print(f.read(100).decode('utf-8'))
...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtm

不用 context manager 方法也能獲得同樣的結(jié)果:

>>>
>>> import urllib.request
>>> f = urllib.request.urlopen('http://www.python.org/')
>>> print(f.read(100).decode('utf-8'))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtm

以下示例將會(huì)把數(shù)據(jù)流發(fā)送給某 CGI 的 stdin,并讀取返回?cái)?shù)據(jù)。請(qǐng)注意,該示例只能工作于 Python 裝有 SSL 支持的環(huán)境。

>>>
>>> import urllib.request
>>> req = urllib.request.Request(url='https://localhost/cgi-bin/test.cgi',
...                       data=b'This data is passed to stdin of the CGI')
>>> with urllib.request.urlopen(req) as f:
...     print(f.read().decode('utf-8'))
...
Got Data: "This data is passed to stdin of the CGI"

上述示例中的 CGI 代碼如下所示:

#!/usr/bin/env python
import sys
data = sys.stdin.read()
print('Content-type: text/plain\n\nGot Data: "%s"' % data)

下面是利用 Request 發(fā)送``PUT`` 請(qǐng)求的示例:

import urllib.request
DATA = b'some data'
req = urllib.request.Request(url='http://localhost:8080', data=DATA, method='PUT')
with urllib.request.urlopen(req) as f:
    pass
print(f.status)
print(f.reason)

基本 HTTP 認(rèn)證示例:

import urllib.request
# Create an OpenerDirector with support for Basic HTTP Authentication...
auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm='PDQ Application',
                          uri='https://mahler:8092/site-updates.py',
                          user='klem',
                          passwd='kadidd!ehopper')
opener = urllib.request.build_opener(auth_handler)
# ...and install it globally so it can be used with urlopen.
urllib.request.install_opener(opener)
urllib.request.urlopen('http://www.example.com/login.html')

build_opener() 默認(rèn)提供了很多現(xiàn)成的 handler,包括 ProxyHandler。 默認(rèn)情況下,ProxyHandler 會(huì)使用名為 <scheme>_proxy 的環(huán)境變量,其中的 <scheme> 是相關(guān)的 URL 協(xié)議。 例如,可以讀取 http_proxy 環(huán)境變量來(lái)獲取 HTTP 代理的 URL。

以下示例將默認(rèn)的 ProxyHandler 替換為自己的 handler,由程序提供代理 URL,并利用 ProxyBasicAuthHandler 加入代理認(rèn)證的支持:

proxy_handler = urllib.request.ProxyHandler({'http': 'http://www.example.com:3128/'})
proxy_auth_handler = urllib.request.ProxyBasicAuthHandler()
proxy_auth_handler.add_password('realm', 'host', 'username', 'password')

opener = urllib.request.build_opener(proxy_handler, proxy_auth_handler)
# This time, rather than install the OpenerDirector, we use it directly:
opener.open('http://www.example.com/login.html')

添加 HTTP 頭部信息:

可利用 Request 構(gòu)造函數(shù)的 headers 參數(shù),或者是:

import urllib.request
req = urllib.request.Request('http://www.example.com/')
req.add_header('Referer', 'http://www.python.org/')
# Customize the default User-Agent header value:
req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)')
r = urllib.request.urlopen(req)

OpenerDirector 自動(dòng)會(huì)在每個(gè) Request 中加入一項(xiàng) User-Agent 頭部信息。若要修改,請(qǐng)參見以下語(yǔ)句:

import urllib.request
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('http://www.example.com/')

另請(qǐng)記得,當(dāng) Request 傳給 urlopen() (或 OpenerDirector.open())時(shí),會(huì)加入一些標(biāo)準(zhǔn)的頭部信息( Content-Length 、 Content-TypeHost)。

以下會(huì)話示例用 GET 方法讀取包含參數(shù)的 URL。

>>>
>>> import urllib.request
>>> import urllib.parse
>>> params = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> url = "http://www.musi-cal.com/cgi-bin/query?%s" % params
>>> with urllib.request.urlopen(url) as f:
...     print(f.read().decode('utf-8'))
...

以下示例換用 POST 方法。請(qǐng)注意 urlencode 輸出結(jié)果先被編碼為字節(jié)串 data,再送入 urlopen。

>>>
>>> import urllib.request
>>> import urllib.parse
>>> data = urllib.parse.urlencode({'spam': 1, 'eggs': 2, 'bacon': 0})
>>> data = data.encode('ascii')
>>> with urllib.request.urlopen("http://requestb.in/xrbl82xr", data) as f:
...     print(f.read().decode('utf-8'))
...

以下示例顯式指定了 HTTP 代理,以覆蓋環(huán)境變量中的設(shè)置:

>>>
>>> import urllib.request
>>> proxies = {'http': 'http://proxy.example.com:8080/'}
>>> opener = urllib.request.FancyURLopener(proxies)
>>> with opener.open("http://www.python.org") as f:
...     f.read().decode('utf-8')
...

以下示例根本不用代理,也覆蓋了環(huán)境變量中的設(shè)置:

>>>
>>> import urllib.request
>>> opener = urllib.request.FancyURLopener({})
>>> with opener.open("http://www.python.org/") as f:
...     f.read().decode('utf-8')
...

已停用的接口?

以下函數(shù)和類是由 Python 2 模塊 urllib``(相對(duì)早于 ``urllib2 )移植過(guò)來(lái)的。將來(lái)某個(gè)時(shí)候可能會(huì)停用。

urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)?

將 URL 形式的網(wǎng)絡(luò)對(duì)象復(fù)制為本地文件。如果 URL 指向本地文件,則必須提供文件名才會(huì)執(zhí)行復(fù)制。返回值為元組 (filename, headers) ,其中 filename 是保存網(wǎng)絡(luò)對(duì)象的本地文件名, headers 是由 urlopen() 返回的遠(yuǎn)程對(duì)象 info() 方法的調(diào)用結(jié)果。可能觸發(fā)的異常與 urlopen() 相同。

第二個(gè)參數(shù)指定文件的保存位置(若未給出,則會(huì)是名稱隨機(jī)生成的臨時(shí)文件)。第三個(gè)參數(shù)是個(gè)可調(diào)用對(duì)象,在建立網(wǎng)絡(luò)連接時(shí)將會(huì)調(diào)用一次,之后每次讀完數(shù)據(jù)塊后會(huì)調(diào)用一次。該可調(diào)用對(duì)象將會(huì)傳入 3 個(gè)參數(shù):已傳輸?shù)膲K數(shù)、塊的大?。ㄒ宰止?jié)為單位)和文件總的大小。如果面對(duì)的是老舊 FTP 服務(wù)器,文件大小參數(shù)可能會(huì)是 -1 ,這些服務(wù)器響應(yīng)讀取請(qǐng)求時(shí)不會(huì)返回文件大小。

以下例子演示了大部分常用場(chǎng)景:

>>>
>>> import urllib.request
>>> local_filename, headers = urllib.request.urlretrieve('http://python.org/')
>>> html = open(local_filename)
>>> html.close()

如果 url 使用 http: 方式的標(biāo)識(shí)符,則可能給出可選的 data 參數(shù)來(lái)指定一個(gè) POST 請(qǐng)求 (通常的請(qǐng)求類型為 GET)。 data 參數(shù)必須是標(biāo)準(zhǔn) application/x-www-form-urlencoded 格式的字節(jié)串對(duì)象;參見 urllib.parse.urlencode() 函數(shù)。

urlretrieve() 在檢測(cè)到可用數(shù)據(jù)少于預(yù)期的大小(即由 Content-Length 標(biāo)頭所報(bào)告的大?。r(shí)將引發(fā) ContentTooShortError。 例如,這可能會(huì)在下載中斷時(shí)發(fā)生。

Content-Length 會(huì)被視為大小的下限:如果存在更多的可用數(shù)據(jù),urlretrieve 會(huì)讀取更多的數(shù)據(jù),但是如果可用數(shù)據(jù)少于該值,則會(huì)引發(fā)異常。

在這種情況下你仍然能夠獲取已下載的數(shù)據(jù),它會(huì)存放在異常實(shí)例的 content 屬性中。

如果未提供 Content-Length 標(biāo)頭,urlretrieve 就無(wú)法檢查它所下載的數(shù)據(jù)大小,只是簡(jiǎn)單地返回它。 在這種情況下你只能假定下載是成功的。

urllib.request.urlcleanup()?

清理之前調(diào)用 urlretrieve() 時(shí)可能留下的臨時(shí)文件。

class urllib.request.URLopener(proxies=None, **x509)?

3.3 版后已移除.

用于打開和讀取 URL 的基類。 除非你需要支持使用 http:, ftp:file: 以外的方式來(lái)打開對(duì)象,那你也許可以使用 FancyURLopener。

在默認(rèn)情況下,URLopener 類會(huì)發(fā)送一個(gè)內(nèi)容為 urllib/VVVUser-Agent 標(biāo)頭,其中 VVVurllib 的版本號(hào)。 應(yīng)用程序可以通過(guò)子類化 URLopenerFancyURLopener 并在子類定義中將類屬性 version 設(shè)為適當(dāng)?shù)淖址祦?lái)定義自己的 User-Agent 標(biāo)頭。

可選的 proxies 形參應(yīng)當(dāng)是一個(gè)將方式名稱映射到代理 URL 的字典,如為空字典則會(huì)完全關(guān)閉代理。 它的默認(rèn)值為 None,在這種情況下如果存在環(huán)境代理設(shè)置則將使用它,正如上文 urlopen() 的定義中所描述的。

一些歸屬于 x509 的額外關(guān)鍵字形參可在使用 https: 方式時(shí)被用于客戶端的驗(yàn)證。 支持通過(guò)關(guān)鍵字 key_filecert_file 來(lái)提供 SSL 密鑰和證書;對(duì)客戶端驗(yàn)證的支持需要提供這兩個(gè)形參。

如果服務(wù)器返回錯(cuò)誤代碼則 URLopener 對(duì)象將引發(fā) OSError 異常。

open(fullurl, data=None)?

使用適當(dāng)?shù)膮f(xié)議打開 fullurl。 此方法會(huì)設(shè)置緩存和代理信息,然后調(diào)用適當(dāng)?shù)拇蜷_方法并附帶其輸入?yún)?shù)。 如果方式無(wú)法被識(shí)別,則會(huì)調(diào)用 open_unknown()。 data 參數(shù)的含義與 urlopen() 中的 data 參數(shù)相同。

此方法總是會(huì)使用 quote() 來(lái)對(duì) fullurl 進(jìn)行轉(zhuǎn)碼。

open_unknown(fullurl, data=None)?

用于打開未知 URL 類型的可重載接口。

retrieve(url, filename=None, reporthook=None, data=None)?

提取 url 的內(nèi)容并將其存放到 filename 中。 返回值為元組,由一個(gè)本地文件名和一個(gè)包含響應(yīng)標(biāo)頭 (對(duì)于遠(yuǎn)程 URL) 的 email.message.Message 對(duì)象或者 None (對(duì)于本地 URL)。 之后調(diào)用方必須打開并讀取 filename 的內(nèi)容。 如果 filename 未給出并且 URL 指向一個(gè)本地文件,則會(huì)返回輸入文件名。 如果 URL 非本地并且 filename 未給出,則文件名為帶有與輸入 URL 的路徑末尾部分后綴相匹配的后綴的 tempfile.mktemp() 的輸出。 如果給出了 reporthook,它必須為接受三個(gè)數(shù)字形參的函數(shù):數(shù)據(jù)分塊編號(hào)、讀入分塊的最大數(shù)據(jù)量和下載的總數(shù)據(jù)量 (未知?jiǎng)t為 -1)。 它將在開始時(shí)和從網(wǎng)絡(luò)讀取每個(gè)數(shù)據(jù)分塊之后被調(diào)用。 對(duì)于本地 URL reporthook 會(huì)被忽略。

如果 url 使用 http: 方式的標(biāo)識(shí)符,則可能給出可選的 data 參數(shù)來(lái)指定一個(gè) POST 請(qǐng)求 (通常的請(qǐng)求類型為 GET)。 data 參數(shù)必須為標(biāo)準(zhǔn)的 application/x-www-form-urlencoded 格式 ;參見 urllib.parse.urlencode() 函數(shù)。

version?

指明打開器對(duì)象的用戶代理名稱的變量。 以便讓 urllib 告訴服務(wù)器它是某個(gè)特定的用戶代理,請(qǐng)?jiān)谧宇愔袑⑵渥鳛轭愖兞縼?lái)設(shè)置或是在調(diào)用基類構(gòu)造器之前在構(gòu)造器中設(shè)置。

class urllib.request.FancyURLopener(...)?

3.3 版后已移除.

FancyURLopener 子類化了 URLopener 以提供對(duì)以下 HTTP 響應(yīng)代碼的默認(rèn)處理: 301, 302, 303, 307 和 401。 對(duì)于上述的 30x 響應(yīng)代碼,會(huì)使用 Location 標(biāo)頭來(lái)獲取實(shí)際 URL。 對(duì)于 401 響應(yīng)代碼 (authentication required),則會(huì)執(zhí)行基本 HTTP 驗(yàn)證。 對(duì)于 30x 響應(yīng)代碼,遞歸層數(shù)會(huì)受 maxtries 屬性值的限制,該值默認(rèn)為 10。

對(duì)于所有其他響應(yīng)代碼,會(huì)調(diào)用 http_error_default() 方法,你可以在子類中重載此方法來(lái)正確地處理錯(cuò)誤。

備注

根據(jù) RFC 2616 的說(shuō)明,對(duì) POST 請(qǐng)求的 301 和 302 響應(yīng)不可在未經(jīng)用戶確認(rèn)的情況下自動(dòng)進(jìn)行重定向。 在現(xiàn)實(shí)情況下,瀏覽器確實(shí)允許自動(dòng)重定義這些響應(yīng),將 POST 更改為 GET,于是 urllib 就會(huì)復(fù)現(xiàn)這種行為。

傳給此構(gòu)造器的形參與 URLopener 的相同。

備注

當(dāng)執(zhí)行基本驗(yàn)證時(shí),FancyURLopener 實(shí)例會(huì)調(diào)用其 prompt_user_passwd() 方法。 默認(rèn)的實(shí)現(xiàn)將向用戶詢問(wèn)控制終端所要求的信息。 如有必要子類可以重載此方法來(lái)支持更適當(dāng)?shù)男袨椤?/p>

FancyURLopener 類附帶了一個(gè)額外方法,它應(yīng)當(dāng)被重載以提供適當(dāng)?shù)男袨?

prompt_user_passwd(host, realm)?

返回指定的安全體系下在給定的主機(jī)上驗(yàn)證用戶所需的信息。 返回的值應(yīng)當(dāng)是一個(gè)元組 (user, password),它可被用于基本驗(yàn)證。

該實(shí)現(xiàn)會(huì)在終端上提示此信息;應(yīng)用程序應(yīng)當(dāng)重載此方法以使用本地環(huán)境下適當(dāng)?shù)慕换ツP汀?/p>

urllib.request 的限制?

  • 目前,僅支持下列協(xié)議: HTTP (0.9 和 1.0 版), FTP, 本地文件, 以及數(shù)據(jù) URL。

    在 3.4 版更改: 增加了對(duì)數(shù)據(jù)URL 的支持。

  • urlretrieve() 的緩存特性已被禁用,等待有人有時(shí)間去正確地解決過(guò)期時(shí)間標(biāo)頭的處理問(wèn)題。

  • 應(yīng)當(dāng)有一個(gè)函數(shù)來(lái)查詢特定 URL 是否在緩存中。

  • 為了保持向下兼容性,如果某個(gè) URL 看起來(lái)是指向本地文件但該文件無(wú)法被打開,則該 URL 會(huì)使用 FTP 協(xié)議來(lái)重新解讀。 這有時(shí)可能會(huì)導(dǎo)致令人迷惑的錯(cuò)誤消息。

  • urlopen()urlretrieve() 函數(shù)在等待網(wǎng)絡(luò)連接建立時(shí)會(huì)導(dǎo)致任意長(zhǎng)時(shí)間的延遲。 這意味著在不使用線程的情況下搭建一個(gè)可交互的 Web 客戶端是非常困難的。

  • urlopen()urlretrieve() 返回的數(shù)據(jù)就是服務(wù)器所返回的原始數(shù)據(jù)。 這可以是二進(jìn)制數(shù)據(jù)(如圖片)、純文本或 HTML 代碼等。 HTTP 協(xié)議在響應(yīng)標(biāo)頭中提供了類型信息,這可以通過(guò)讀取 Content-Type 標(biāo)頭來(lái)查看。 如果返回的數(shù)據(jù)是 HTML,你可以使用 html.parser 模塊來(lái)解析它。

  • 處理 FTP 協(xié)議的代碼無(wú)法區(qū)分文件和目錄。 這在嘗試讀取指向不可訪問(wèn)的 URL 時(shí)可能導(dǎo)致意外的行為。 如果 URL 以一個(gè) / 結(jié)束,它會(huì)被認(rèn)為指向一個(gè)目錄并將作相應(yīng)的處理。 但是如果讀取一個(gè)文件的嘗試導(dǎo)致了 550 錯(cuò)誤(表示 URL 無(wú)法找到或不可訪問(wèn),這常常是由于權(quán)限原因),則該路徑會(huì)被視為一個(gè)目錄以便處理 URL 是指定一個(gè)目錄但略去了末尾 / 的情況。 這在你嘗試獲取一個(gè)因其設(shè)置了讀取權(quán)限因而無(wú)法訪問(wèn)的文件時(shí)會(huì)造成誤導(dǎo)性的結(jié)果;FTP 代碼將嘗試讀取它,因 550 錯(cuò)誤而失敗,然后又為這個(gè)不可讀取的文件執(zhí)行目錄列表操作。 如果需要細(xì)粒度的控制,請(qǐng)考慮使用 ftplib 模塊,子類化 FancyURLopener,或是修改 _urlopener 來(lái)滿足你的需求。

urllib.response --- urllib 使用的 Response 類?

urllib.response 模塊定義了一些函數(shù)和提供最小化文件類接口包括 read()readline() 等的類。 此模塊定義的函數(shù)會(huì)由 urllib.request 模塊在內(nèi)部使用。 典型的響應(yīng)對(duì)象是一個(gè) urllib.response.addinfourl 實(shí)例:

class urllib.response.addinfourl?
url?

已讀取資源的 URL,通常用于確定是否進(jìn)行了重定向。

headers?

EmailMessage 實(shí)例的形式返回響應(yīng)的標(biāo)頭。

status?

3.9 新版功能.

由服務(wù)器返回的狀態(tài)碼。

geturl()?

3.9 版后已移除: 已棄用,建議改用 url。

info()?

3.9 版后已移除: 已棄用,建議改用 headers。

code?

3.9 版后已移除: 已棄用,建議改用 status。

getstatus()?

3.9 版后已移除: 已棄用,建議改用 status。