urllib.request
— 用於開啟 URL 的可擴充套件庫¶
urllib.request
模組定義了在複雜環境中幫助開啟 URL(主要是 HTTP)的函式和類 — 基本身份驗證和摘要式身份驗證、重定向、cookie 等。
另請參閱
建議使用 Requests 包 作為更高級別的 HTTP 客戶端介面。
警告
在 macOS 上,在使用了 os.fork()
的程式中使用此模組是不安全的,因為 macOS 的 getproxies()
實現使用更高級別的系統 API。 將環境變數 no_proxy
設定為 *
以避免此問題(例如 os.environ["no_proxy"] = "*"
)。
可用性:非 WASI。
此模組在 WebAssembly 上無法工作或不可用。 有關詳細資訊,請參閱 WebAssembly 平臺。
urllib.request
模組定義了以下函式
- urllib.request.urlopen(url, data=None, [timeout, ]*, context=None)¶
開啟 url,它可以是包含有效、正確編碼的 URL 的字串,也可以是
Request
物件。data 必須是一個指定要傳送到伺服器的附加資料的物件,如果不需要此類資料,則為
None
。有關詳細資訊,請參閱Request
。urllib.request 模組使用 HTTP/1.1 並在其 HTTP 請求中包含
Connection:close
標頭。可選的 timeout 引數指定阻塞操作(如連線嘗試)的超時時間(以秒為單位)(如果未指定,則將使用全域性預設超時設定)。 這實際上僅適用於 HTTP、HTTPS 和 FTP 連線。
如果指定了 context,則它必須是描述各種 SSL 選項的
ssl.SSLContext
例項。 有關詳細資訊,請參閱HTTPSConnection
。此函式始終返回一個可以作為 上下文管理器 並且具有屬性 url、headers 和 status 的物件。 有關這些屬性的更多詳細資訊,請參閱
urllib.response.addinfourl
。對於 HTTP 和 HTTPS URL,此函式返回一個經過稍微修改的
http.client.HTTPResponse
物件。 除了上面的三個新方法之外,msg 屬性包含與reason
屬性相同的資訊 — 伺服器返回的原因短語 — 而不是HTTPResponse
文件中指定的響應頭。對於 FTP、檔案和資料 URL 以及由舊版
URLopener
和FancyURLopener
類顯式處理的請求,此函式返回一個urllib.response.addinfourl
物件。在協議錯誤時引發
URLError
。請注意,如果沒有處理請求的處理程式,則可能會返回
None
(儘管預設安裝的全域性OpenerDirector
使用UnknownHandler
來確保這種情況永遠不會發生)。此外,如果檢測到代理設定(例如,當設定了
*_proxy
環境變數(如http_proxy
)時),則預設安裝ProxyHandler
並確保請求透過代理處理。來自 Python 2.6 及更早版本的舊版
urllib.urlopen
函式已停用;urllib.request.urlopen()
對應於舊的urllib2.urlopen
。 可以透過使用ProxyHandler
物件來獲得以前透過將字典引數傳遞給urllib.urlopen
來完成的代理處理。預設的 opener 引發一個 審計事件
urllib.Request
,其引數fullurl
、data
、headers
和method
取自請求物件。在 3.3 版本中更改: 添加了 cadefault。
在 3.4.3 版本中更改: 添加了 context。
在 3.10 版本中變更: 當沒有提供context時,HTTPS 連線現在會發送一個帶有協議指示符
http/1.1
的 ALPN 擴充套件。自定義的 context 應該使用set_alpn_protocols()
設定 ALPN 協議。在 3.13 版本中變更: 移除 cafile、capath 和 cadefault 引數:請改用 context 引數。
- urllib.request.install_opener(opener)¶
將
OpenerDirector
例項安裝為預設的全域性 opener。只有當你想讓 urlopen 使用該 opener 時,才需要安裝一個 opener;否則,只需呼叫OpenerDirector.open()
而不是urlopen()
。程式碼不會檢查是否為真正的OpenerDirector
,任何具有適當介面的類都可以工作。
- urllib.request.build_opener([handler, ...])¶
返回一個
OpenerDirector
例項,它按照給定的順序連結處理程式。handler 可以是BaseHandler
的例項,或者BaseHandler
的子類(在這種情況下,必須可以呼叫不帶任何引數的建構函式)。除非 handler 包含以下類的例項、它們的子類或例項:ProxyHandler
(如果檢測到代理設定)、UnknownHandler
、HTTPHandler
、HTTPDefaultErrorHandler
、HTTPRedirectHandler
、FTPHandler
、FileHandler
、HTTPErrorProcessor
,否則這些類的例項將在 handler 之前。如果 Python 安裝支援 SSL(即,如果可以匯入
ssl
模組),也會新增HTTPSHandler
。BaseHandler
的子類也可以更改其handler_order
屬性,以修改其在處理程式列表中的位置。
- urllib.request.pathname2url(path)¶
將給定的本地路徑轉換為
file:
URL。此函式使用quote()
函式對路徑進行編碼。出於歷史原因,返回值省略了file:
方案字首。此示例展示瞭如何在 Windows 上使用該函式>>> from urllib.request import pathname2url >>> path = 'C:\\Program Files' >>> 'file:' + pathname2url(path) 'file:///C:/Program%20Files'
- urllib.request.url2pathname(url)¶
將給定的
file:
URL 轉換為本地路徑。此函式使用unquote()
來解碼 URL。出於歷史原因,給定的值必須省略file:
方案字首。此示例展示瞭如何在 Windows 上使用該函式>>> from urllib.request import url2pathname >>> url = 'file:///C:/Program%20Files' >>> url2pathname(url.removeprefix('file:')) 'C:\\Program Files'
- urllib.request.getproxies()¶
此幫助函式返回一個從 scheme 到代理伺服器 URL 對映的字典。它首先掃描所有作業系統的環境中名為
<scheme>_proxy
的變數(不區分大小寫),如果找不到,則從 macOS 的系統配置和 Windows 的 Windows 系統登錄檔中查詢代理資訊。如果存在小寫和大寫環境變數(並且不一致),則優先使用小寫。注意
如果設定了環境變數
REQUEST_METHOD
,這通常表明你的指令碼在 CGI 環境中執行,則會忽略環境變數HTTP_PROXY
(大寫_PROXY
)。這是因為該變數可以由客戶端使用“Proxy:” HTTP 標頭注入。如果你需要在 CGI 環境中使用 HTTP 代理,請顯式使用ProxyHandler
,或者確保變數名稱為小寫(或至少是_proxy
字尾)。
提供以下類
- class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)¶
此類是 URL 請求的抽象。
url 應該是一個包含有效且正確編碼的 URL 的字串。
data 必須是一個指定要傳送到伺服器的附加資料的物件,如果不需要此類資料,則為
None
。目前只有 HTTP 請求使用 data。支援的物件型別包括位元組、類檔案物件和位元組類物件的可迭代物件。如果沒有提供Content-Length
或Transfer-Encoding
標頭欄位,HTTPHandler
將根據 data 的型別設定這些標頭。Content-Length
將用於傳送位元組物件,而 RFC 7230 第 3.3.1 節中指定的Transfer-Encoding: chunked
將用於傳送檔案和其他可迭代物件。對於 HTTP POST 請求方法,data 應該是標準 application/x-www-form-urlencoded 格式的緩衝區。
urllib.parse.urlencode()
函式接收對映或 2 元組序列,並返回此格式的 ASCII 字串。在用作 data 引數之前,應將其編碼為位元組。headers 應該是一個字典,並且將被視為呼叫了
add_header()
,其中每個鍵和值作為引數。這通常用於“欺騙”User-Agent
標頭值,該標頭值被瀏覽器用於標識自身——某些 HTTP 伺服器只允許來自常見瀏覽器而不是指令碼的請求。例如,Mozilla Firefox 可能將自己標識為"Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11"
,而urllib
的預設使用者代理字串是"Python-urllib/2.6"
(在 Python 2.6 上)。所有標頭鍵都以駝峰式大小寫傳送。如果存在 data 引數,則應包含適當的
Content-Type
標頭。如果沒有提供此標頭,並且 data 不是None
,則會新增Content-Type: application/x-www-form-urlencoded
作為預設值。接下來的兩個引數僅對正確處理第三方 HTTP Cookie 感興趣
origin_req_host 應該是 RFC 2965 定義的原始事務的請求主機。它預設為
http.cookiejar.request_host(self)
。這是使用者發起的原始請求的主機名或 IP 地址。例如,如果請求的是 HTML 文件中的影像,則這應該是包含該影像的頁面請求的請求主機。unverifiable 應該指明請求是否不可驗證,其定義遵循 RFC 2965。 預設為
False
。不可驗證的請求是指使用者沒有選擇批准的 URL 請求。 例如,如果請求是 HTML 文件中的影像,並且使用者沒有選擇批准自動獲取影像,則此值應為 true。method 應該是一個字串,表示將要使用的 HTTP 請求方法(例如,
'HEAD'
)。如果提供此引數,它的值將儲存在method
屬性中,並被get_method()
方法使用。如果 data 是None
,則預設值為'GET'
,否則為'POST'
。子類可以透過在類本身中設定method
屬性來指示不同的預設方法。注意
如果資料物件無法多次傳遞其內容(例如,檔案或只能產生一次內容的可迭代物件),並且由於 HTTP 重定向或身份驗證而重試請求,則請求將無法按預期工作。data 在標頭之後立即傳送到 HTTP 伺服器。該庫不支援 100-continue 期望。
在 3.3 版本中變更:
Request.method
引數被新增到 Request 類中。在 3.4 版本中變更: 預設的
Request.method
可以在類級別中指定。在 3.6 版本中變更: 如果未提供
Content-Length
並且 data 既不是None
也不是位元組物件,則不會引發錯誤。回退到使用分塊傳輸編碼。
- class urllib.request.OpenerDirector¶
OpenerDirector
類透過連結在一起的BaseHandler
開啟 URL。 它管理處理程式的連結和從錯誤中恢復。
- class urllib.request.BaseHandler¶
這是所有已註冊處理程式的基本類,並且僅處理註冊的簡單機制。
- class urllib.request.HTTPRedirectHandler¶
一個處理重定向的類。
- class urllib.request.HTTPCookieProcessor(cookiejar=None)¶
一個處理 HTTP Cookie 的類。
- class urllib.request.ProxyHandler(proxies=None)¶
使請求透過代理。 如果給出 proxies,則它必須是一個將協議名稱對映到代理 URL 的字典。 預設是從環境變數
<protocol>_proxy
讀取代理列表。 如果未設定代理環境變數,則在 Windows 環境中,代理設定從登錄檔的 Internet 設定部分獲取,在 macOS 環境中,代理資訊從系統配置框架檢索。要停用自動檢測的代理,請傳遞一個空字典。
可以使用
no_proxy
環境變數來指定不應透過代理訪問的主機; 如果設定了,它應該是一個以逗號分隔的主機名字尾列表,可以選擇附加:port
,例如cern.ch,ncsa.uiuc.edu,some.host:8080
。注意
如果設定了變數
REQUEST_METHOD
,則將忽略HTTP_PROXY
;請參閱關於getproxies()
的文件。
- class urllib.request.HTTPPasswordMgr¶
保留
(realm, uri) -> (user, password)
對映的資料庫。
- class urllib.request.HTTPPasswordMgrWithDefaultRealm¶
保留
(realm, uri) -> (user, password)
對映的資料庫。None
的 realm 被視為捕獲所有 realm,如果沒有其他 realm 匹配,則搜尋該 realm。
- class urllib.request.HTTPPasswordMgrWithPriorAuth¶
HTTPPasswordMgrWithDefaultRealm
的一個變體,它還有一個uri -> is_authenticated
對映的資料庫。 BasicAuth 處理程式可以使用它來確定何時立即傳送身份驗證憑據,而不是等待401
響應。在 3.5 版本中新增。
- class urllib.request.AbstractBasicAuthHandler(password_mgr=None)¶
這是一個混合類,有助於進行 HTTP 身份驗證,包括對遠端主機和代理的身份驗證。如果給定了 password_mgr,則它應該與
HTTPPasswordMgr
相容;有關必須支援的介面的資訊,請參閱 HTTPPasswordMgr 物件 部分。如果 passwd_mgr 還提供了is_authenticated
和update_authenticated
方法(請參閱 HTTPPasswordMgrWithPriorAuth 物件),則處理程式將使用給定 URI 的is_authenticated
結果來確定是否在請求中傳送身份驗證憑據。如果is_authenticated
為 URI 返回True
,則會發送憑據。如果is_authenticated
為False
,則不傳送憑據,然後如果收到401
響應,則會使用身份驗證憑據重新發送請求。如果身份驗證成功,則呼叫update_authenticated
將 URI 的is_authenticated
設定為True
,以便隨後對該 URI 或其任何父 URI 的請求將自動包含身份驗證憑據。在 3.5 版本中新增: 添加了
is_authenticated
支援。
- class urllib.request.HTTPBasicAuthHandler(password_mgr=None)¶
處理與遠端主機的身份驗證。password_mgr(如果提供)應與
HTTPPasswordMgr
相容;有關必須支援的介面資訊,請參閱 HTTPPasswordMgr 物件 部分。當遇到錯誤的身份驗證方案時,HTTPBasicAuthHandler 將引發ValueError
。
- class urllib.request.ProxyBasicAuthHandler(password_mgr=None)¶
處理與代理的身份驗證。password_mgr(如果提供)應與
HTTPPasswordMgr
相容;有關必須支援的介面資訊,請參閱 HTTPPasswordMgr 物件 部分。
- class urllib.request.AbstractDigestAuthHandler(password_mgr=None)¶
這是一個輔助 HTTP 身份驗證的混合類,用於遠端主機和代理。password_mgr(如果提供)應與
HTTPPasswordMgr
相容;有關必須支援的介面資訊,請參閱 HTTPPasswordMgr 物件 部分。
- class urllib.request.HTTPDigestAuthHandler(password_mgr=None)¶
處理與遠端主機的身份驗證。password_mgr(如果提供)應與
HTTPPasswordMgr
相容;有關必須支援的介面資訊,請參閱 HTTPPasswordMgr 物件 部分。當同時新增摘要身份驗證處理程式和基本身份驗證處理程式時,總是首先嚐試摘要身份驗證。如果摘要身份驗證再次返回 40x 響應,則將其傳送給基本身份驗證處理程式進行處理。當遇到摘要或基本身份驗證方案之外的身份驗證方案時,此處理程式方法將引發ValueError
。在 3.3 版本中更改: 當不支援身份驗證方案時,引發
ValueError
。
- class urllib.request.ProxyDigestAuthHandler(password_mgr=None)¶
處理與代理的身份驗證。password_mgr(如果提供)應與
HTTPPasswordMgr
相容;有關必須支援的介面資訊,請參閱 HTTPPasswordMgr 物件 部分。
- class urllib.request.HTTPHandler¶
一個處理開啟 HTTP URL 的類。
- class urllib.request.HTTPSHandler(debuglevel=0, context=None, check_hostname=None)¶
一個處理開啟 HTTPS URL 的類。context 和 check_hostname 的含義與
http.client.HTTPSConnection
中相同。在 3.2 版本中更改: 添加了 context 和 check_hostname。
- class urllib.request.FileHandler¶
開啟本地檔案。
- class urllib.request.DataHandler¶
開啟資料 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¶
處理 HTTP 錯誤響應。
請求物件¶
以下方法描述了 Request
的公共介面,因此都可以在子類中被重寫。它還定義了幾個公共屬性,客戶端可以使用這些屬性來檢查已解析的請求。
- Request.full_url¶
傳遞給建構函式的原始 URL。
在 3.4 版本中更改。
Request.full_url 是一個具有設定器、獲取器和刪除器的屬性。獲取
full_url
會返回帶有片段(如果存在)的原始請求 URL。
- Request.type¶
URI 方案。
- Request.host¶
URI 授權,通常是主機,但也可能包含一個用冒號分隔的埠。
- Request.origin_req_host¶
請求的原始主機,不帶埠。
- Request.data¶
請求的實體主體,如果未指定,則為
None
。在 3.4 版本中更改: 更改
Request.data
的值現在會刪除之前設定或計算的“Content-Length”標頭。
- Request.method¶
要使用的 HTTP 請求方法。預設情況下,其值為
None
,這意味著get_method()
將執行其正常的計算以確定要使用的方法。可以透過在Request
子類中在類級別設定預設值,或者透過在Request
建構函式中透過 method 引數傳遞值來設定其值(從而覆蓋get_method()
中的預設計算)。3.3 版本中新增。
在 3.4 版本中更改: 現在可以在子類中設定預設值;之前只能透過建構函式引數設定。
- Request.get_method()¶
返回一個字串,指示 HTTP 請求方法。如果
Request.method
不是None
,則返回其值,否則如果Request.data
為None
,則返回'GET'
,如果不是,則返回'POST'
。這僅對 HTTP 請求有意義。在 3.3 版本中更改: get_method 現在會檢視
Request.method
的值。
- Request.add_header(key, val)¶
向請求新增另一個標頭。目前,除了 HTTP 處理程式之外,所有處理程式都會忽略標頭,在 HTTP 處理程式中,它們會被新增到傳送到伺服器的標頭列表中。請注意,不能存在多個具有相同名稱的標頭,並且如果 key 衝突,則後面的呼叫將覆蓋之前的呼叫。目前,這不會損失 HTTP 功能,因為所有多次使用時有意義的標頭都有(標頭特定的)方法僅使用一個標頭即可獲得相同的功能。請注意,使用此方法新增的標頭也會新增到重定向的請求中。
- Request.add_unredirected_header(key, header)¶
新增一個不會新增到重定向請求的標頭。
- Request.has_header(header)¶
返回例項是否具有指定名稱的標頭(檢查常規標頭和未重定向的標頭)。
- Request.remove_header(header)¶
從請求例項中刪除指定名稱的標頭(從常規標頭和未重定向的標頭中刪除)。
在 3.4 版本中新增。
- Request.get_full_url()¶
返回建構函式中給定的 URL。
在 3.4 版本中更改。
- Request.set_proxy(host, type)¶
透過連線到代理伺服器來準備請求。host 和 type 將替換例項中的值,並且例項的選擇器將是建構函式中給定的原始 URL。
- Request.get_header(header_name, default=None)¶
返回給定標頭的值。如果標頭不存在,則返回預設值。
- Request.header_items()¶
返回請求標頭的元組列表 (header_name, header_value)。
在 3.4 版本中更改: 自 3.3 版本起已棄用的請求方法 add_data、has_data、get_data、get_type、get_host、get_selector、get_origin_req_host 和 is_unverifiable 已被刪除。
OpenerDirector 物件¶
OpenerDirector
例項具有以下方法
- OpenerDirector.add_handler(handler)¶
handler 應該是
BaseHandler
的例項。將搜尋以下方法,並將其新增到可能的鏈中(請注意,HTTP 錯誤是一個特殊情況)。請注意,在以下內容中,protocol 應替換為要處理的實際協議,例如http_response()
將是 HTTP 協議響應處理程式。另外,type 應替換為實際的 HTTP 程式碼,例如http_error_404()
將處理 HTTP 404 錯誤。<protocol>_open()
— 表示處理程式知道如何開啟 protocol URL。有關更多資訊,請參見
BaseHandler.<protocol>_open()
。http_error_<type>()
— 表示處理程式知道如何處理具有 HTTP 錯誤程式碼 type 的 HTTP 錯誤。有關更多資訊,請參見
BaseHandler.http_error_<nnn>()
。<protocol>_error()
— 表示處理程式知道如何處理來自(非http
)protocol 的錯誤。<protocol>_request()
— 表示處理程式知道如何預處理 protocol 請求。有關更多資訊,請參見
BaseHandler.<protocol>_request()
。<protocol>_response()
— 表示處理程式知道如何後處理 protocol 響應。有關更多資訊,請參見
BaseHandler.<protocol>_response()
。
- OpenerDirector.open(url, data=None[, timeout])¶
開啟給定的 url(可以是請求物件或字串),可以選擇傳遞給定的 data。引數、返回值和引發的異常與
urlopen()
的相同(後者只是在當前安裝的全域性OpenerDirector
上呼叫open()
方法)。可選的 timeout 引數指定阻塞操作的超時時間(以秒為單位),例如連線嘗試(如果未指定,則將使用全域性預設超時設定)。超時功能實際上僅適用於 HTTP、HTTPS 和 FTP 連線。
- OpenerDirector.error(proto, *args)¶
處理給定協議的錯誤。這將使用給定的引數(特定於協議)呼叫給定協議的已註冊錯誤處理程式。HTTP 協議是一種特殊情況,它使用 HTTP 響應程式碼來確定特定的錯誤處理程式;請參閱處理程式類的
http_error_<type>()
方法。返回值和引發的異常與
urlopen()
的相同。
OpenerDirector 物件分三個階段開啟 URL
每個階段中呼叫這些方法的順序由處理程式例項的排序決定。
每個具有名為
<protocol>_request()
的方法的處理程式都會呼叫該方法來預處理請求。具有名為
<protocol>_open()
的方法的處理程式被呼叫來處理請求。當處理程式返回一個非None
值(即響應)或引發異常(通常是URLError
)時,此階段結束。允許異常傳播。實際上,首先嚐試對名為
default_open()
的方法使用上述演算法。如果所有此類方法都返回None
,則對名為<protocol>_open()
的方法重複該演算法。如果所有此類方法都返回None
,則對名為unknown_open()
的方法重複該演算法。請注意,這些方法的實現可能涉及呼叫父
OpenerDirector
例項的open()
和error()
方法。每個具有名為
<protocol>_response()
的方法的處理程式都會呼叫該方法來後處理響應。
BaseHandler 物件¶
BaseHandler
物件提供了一些直接有用的方法,以及其他一些旨在由派生類使用的方法。這些旨在直接使用
- BaseHandler.add_parent(director)¶
新增一個 director 作為父級。
- BaseHandler.close()¶
移除所有父級。
以下屬性和方法應僅由從 BaseHandler
派生的類使用。
注意
已經採用的慣例是,定義 <protocol>_request()
或 <protocol>_response()
方法的子類命名為 *Processor
;所有其他子類都命名為 *Handler
。
- BaseHandler.parent¶
一個有效的
OpenerDirector
,可用於使用不同的協議開啟或處理錯誤。
- BaseHandler.default_open(req)¶
此方法在
BaseHandler
中未定義,但如果子類想要捕獲所有 URL,則應定義它。如果實現此方法,則父
OpenerDirector
將呼叫它。它應返回一個類似檔案的物件,如open()
方法的返回值中所述OpenerDirector
,或者None
。它應該引發URLError
,除非發生真正特殊的事情(例如,MemoryError
不應對映到URLError
)。此方法將在任何特定於協議的 open 方法之前呼叫。
- BaseHandler.<protocol>_open(req)
此方法在
BaseHandler
中未定義,但如果子類想要處理具有給定協議的 URL,則應定義它。如果定義了此方法,則父
OpenerDirector
將呼叫它。返回值應與default_open()
的返回值相同。
- BaseHandler.unknown_open(req)¶
此方法在
BaseHandler
中未定義,但如果子類想要捕獲所有沒有特定註冊處理程式來開啟它的 URL,則應定義它。如果實現此方法,則
parent
OpenerDirector
將呼叫它。返回值應與default_open()
的返回值相同。
- BaseHandler.http_error_default(req, fp, code, msg, hdrs)¶
此方法在
BaseHandler
中未定義,但如果子類打算為未處理的 HTTP 錯誤提供捕獲所有方法,則應覆蓋它。它將由獲取錯誤的OpenerDirector
自動呼叫,並且通常不應在其他情況下呼叫。req 將是
Request
物件,fp 將是具有 HTTP 錯誤主體的類似檔案的物件,code 將是錯誤的三位數程式碼,msg 將是程式碼的使用者可見解釋,hdrs 將是具有錯誤標頭的對映物件。返回值和引發的異常應與
urlopen()
的相同。
- BaseHandler.http_error_<nnn>(req, fp, code, msg, hdrs)
nnn 應該是一個三位數的 HTTP 錯誤程式碼。這個方法也沒有在
BaseHandler
中定義,但是當發生程式碼為 nnn 的 HTTP 錯誤時,如果子類的例項中存在該方法,它將被呼叫。子類應該重寫此方法來處理特定的 HTTP 錯誤。
引數、返回值和引發的異常應該與
http_error_default()
相同。
- BaseHandler.<協議>_request(req)
此方法沒有在
BaseHandler
中定義,但是如果子類想要預處理給定協議的請求,則應該定義它。如果定義了此方法,則父級
OpenerDirector
將會呼叫它。req 將是一個Request
物件。返回值應該是一個Request
物件。
- BaseHandler.<協議>_response(req, response)
此方法沒有在
BaseHandler
中定義,但是如果子類想要後處理給定協議的響應,則應該定義它。如果定義了此方法,則父級
OpenerDirector
將會呼叫它。req 將是一個Request
物件。response 將是一個實現與urlopen()
返回值相同介面的物件。返回值應該實現與urlopen()
返回值相同的介面。
HTTPRedirectHandler 物件¶
注意
一些 HTTP 重定向需要此模組的客戶端程式碼執行操作。如果出現這種情況,將引發 HTTPError
異常。有關各種重定向程式碼的確切含義的詳細資訊,請參見 RFC 2616。
如果 HTTPRedirectHandler 接收到的重定向 URL 不是 HTTP、HTTPS 或 FTP URL,則會出於安全考慮引發 HTTPError
異常。
- HTTPRedirectHandler.redirect_request(req, fp, code, msg, hdrs, newurl)¶
返回一個
Request
或None
來響應重定向。當從伺服器接收到重定向時,http_error_30*()
方法的預設實現會呼叫此方法。如果應該發生重定向,則返回一個新的Request
,以便http_error_30*()
可以執行到 newurl 的重定向。否則,如果沒有其他處理程式應嘗試處理此 URL,則引發HTTPError
,如果您無法處理但其他處理程式可能會處理,則返回None
。注意
此方法的預設實現並不嚴格遵循 RFC 2616,該規範規定,未經使用者確認,不得自動重定向對
POST
請求的 301 和 302 響應。實際上,瀏覽器確實允許自動重定向這些響應,將 POST 更改為GET
,並且預設實現會重現此行為。
- HTTPRedirectHandler.http_error_301(req, fp, code, msg, hdrs)¶
重定向到
Location:
或URI:
URL。當收到 HTTP “永久移動” 響應時,父級OpenerDirector
會呼叫此方法。
- HTTPRedirectHandler.http_error_302(req, fp, code, msg, hdrs)¶
與
http_error_301()
相同,但是為“已找到”響應呼叫。
- HTTPRedirectHandler.http_error_303(req, fp, code, msg, hdrs)¶
與
http_error_301()
相同,但是為“檢視其他”響應呼叫。
- HTTPRedirectHandler.http_error_307(req, fp, code, msg, hdrs)¶
與
http_error_301()
相同,但是為“臨時重定向”響應呼叫。它不允許將請求方法從POST
更改為GET
。
- HTTPRedirectHandler.http_error_308(req, fp, code, msg, hdrs)¶
與
http_error_301()
相同,但是為“永久重定向”響應呼叫。它不允許將請求方法從POST
更改為GET
。在 3.11 版本中新增。
ProxyHandler 物件¶
- ProxyHandler.<協議>_open(request)
對於建構函式中給定的 proxies 字典中具有代理的每個協議,
ProxyHandler
都將有一個方法<protocol>_open()
。該方法將透過呼叫request.set_proxy()
修改請求以透過代理,並呼叫鏈中的下一個處理程式來實際執行協議。
HTTPPasswordMgr 物件¶
這些方法在 HTTPPasswordMgr
和 HTTPPasswordMgrWithDefaultRealm
物件上可用。
- HTTPPasswordMgr.add_password(realm, uri, user, passwd)¶
uri 可以是單個 URI,也可以是 URI 序列。 realm、user 和 passwd 必須是字串。這將導致在給出 realm 和任何給定 URI 的超級 URI 的身份驗證時,將使用
(user, passwd)
作為身份驗證令牌。
- HTTPPasswordMgr.find_user_password(realm, authuri)¶
獲取給定 realm 和 URI 的使用者/密碼(如果有)。如果沒有匹配的使用者/密碼,此方法將返回
(None, None)
。對於
HTTPPasswordMgrWithDefaultRealm
物件,如果給定的 realm 沒有匹配的使用者/密碼,則會搜尋 realmNone
。
HTTPPasswordMgrWithPriorAuth 物件¶
此密碼管理器擴充套件了 HTTPPasswordMgrWithDefaultRealm
,以支援跟蹤應始終傳送身份驗證憑據的 URI。
- HTTPPasswordMgrWithPriorAuth.add_password(realm, uri, user, passwd, is_authenticated=False)¶
realm、uri、user、passwd 與
HTTPPasswordMgr.add_password()
相同。is_authenticated 設定給定 URI 或 URI 列表的is_authenticated
標誌的初始值。如果 is_authenticated 指定為True
,則忽略 realm。
- HTTPPasswordMgrWithPriorAuth.find_user_password(realm, authuri)¶
- HTTPPasswordMgrWithPriorAuth.update_authenticated(self, uri, is_authenticated=False)¶
更新給定 uri 或 URI 列表的
is_authenticated
標誌。
- HTTPPasswordMgrWithPriorAuth.is_authenticated(self, authuri)¶
返回給定 URI 的
is_authenticated
標誌的當前狀態。
AbstractBasicAuthHandler 物件¶
- AbstractBasicAuthHandler.http_error_auth_reqed(authreq, host, req, headers)¶
透過獲取使用者/密碼對並重試請求來處理身份驗證請求。authreq 應該是標頭的名稱,該標頭中包含有關請求中 realm 的資訊,host 指定要進行身份驗證的 URL 和路徑,req 應該是(失敗的)
Request
物件,而 headers 應該是錯誤標頭。host 是授權機構(例如,
"python.org"
)或包含授權機構元件的 URL(例如,"https://python.club.tw/"
)。在任何一種情況下,授權機構都不得包含 userinfo 元件(因此,"python.org"
和"python.org:80"
沒問題,"joe:password@python.org"
則不行)。
HTTPBasicAuthHandler 物件¶
- HTTPBasicAuthHandler.http_error_401(req, fp, code, msg, hdrs)¶
如果可用,則使用身份驗證資訊重試請求。
ProxyBasicAuthHandler 物件¶
- ProxyBasicAuthHandler.http_error_407(req, fp, code, msg, hdrs)¶
如果可用,則使用身份驗證資訊重試請求。
AbstractDigestAuthHandler 物件¶
HTTPDigestAuthHandler 物件¶
- HTTPDigestAuthHandler.http_error_401(req, fp, code, msg, hdrs)¶
如果可用,則使用身份驗證資訊重試請求。
ProxyDigestAuthHandler 物件¶
- ProxyDigestAuthHandler.http_error_407(req, fp, code, msg, hdrs)¶
如果可用,則使用身份驗證資訊重試請求。
HTTPHandler 物件¶
- HTTPHandler.http_open(req)¶
傳送一個 HTTP 請求,它可以是 GET 或 POST,具體取決於
req.has_data()
。
HTTPSHandler 物件¶
- HTTPSHandler.https_open(req)¶
傳送一個 HTTPS 請求,它可以是 GET 或 POST,具體取決於
req.has_data()
。
FileHandler 物件¶
DataHandler 物件¶
- DataHandler.data_open(req)¶
讀取資料 URL。這種 URL 包含 URL 本身編碼的內容。資料 URL 語法在 RFC 2397 中指定。此實現忽略 base64 編碼資料 URL 中的空格,因此 URL 可以包裝在它來自的任何原始檔中。但是,即使某些瀏覽器不介意 base64 編碼資料 URL 末尾缺少填充,此實現也會在這種情況下引發
ValueError
。
FTPHandler 物件¶
- FTPHandler.ftp_open(req)¶
開啟 req 指示的 FTP 檔案。登入始終使用空的使用者名稱和密碼。
CacheFTPHandler 物件¶
CacheFTPHandler
物件是 FTPHandler
物件,具有以下附加方法
- CacheFTPHandler.setTimeout(t)¶
將連線的超時時間設定為 t 秒。
- CacheFTPHandler.setMaxConns(m)¶
將快取連線的最大數量設定為 m。
UnknownHandler 物件¶
HTTPErrorProcessor 物件¶
- HTTPErrorProcessor.http_response(request, response)¶
處理 HTTP 錯誤響應。
對於 200 錯誤程式碼,立即返回 response 物件。
對於非 200 錯誤程式碼,這只是透過
OpenerDirector.error()
將任務傳遞給http_error_<type>()
處理方法。最終,如果沒有其他處理程式處理該錯誤,HTTPDefaultErrorHandler
將引發HTTPError
。
- HTTPErrorProcessor.https_response(request, response)¶
處理 HTTPS 錯誤響應。
行為與
http_response()
相同。
示例¶
除了下面的示例外,在 如何使用 urllib 包獲取網際網路資源 中還提供了更多示例。
此示例獲取 python.org 主頁並顯示其前 300 個位元組。
>>> import urllib.request
>>> with urllib.request.urlopen('https://python.club.tw/') 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 '
請注意,urlopen 返回一個位元組物件。這是因為 urlopen 無法自動確定它從 HTTP 伺服器接收的位元組流的編碼。通常,程式在確定或猜測適當的編碼後,會將返回的位元組物件解碼為字串。
以下 W3C 文件 https://www.w3.org/International/O-charset 列出了 (X)HTML 或 XML 文件可以指定其編碼資訊的各種方式。
由於 python.org 網站使用其元標記中指定的 utf-8 編碼,我們將使用相同的編碼來解碼位元組物件。
>>> with urllib.request.urlopen('https://python.club.tw/') 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
也可以在不使用 上下文管理器 方法的情況下實現相同的結果。
>>> import urllib.request
>>> f = urllib.request.urlopen('https://python.club.tw/')
>>> 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
在以下示例中,我們將資料流傳送到 CGI 的 stdin 並讀取它返回給我們的資料。請注意,此示例僅在 Python 安裝支援 SSL 時才有效。
>>> import urllib.request
>>> req = urllib.request.Request(url='https:///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
執行 PUT
請求的示例
import urllib.request
DATA = b'some data'
req = urllib.request.Request(url='https://:8080', data=DATA, method='PUT')
with urllib.request.urlopen(req) as f:
pass
print(f.status)
print(f.reason)
使用基本 HTTP 身份驗證
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()
預設情況下提供許多處理程式,包括 ProxyHandler
。預設情況下,ProxyHandler
使用名為 <scheme>_proxy
的環境變數,其中 <scheme>
是涉及的 URL 方案。例如,讀取 http_proxy
環境變數以獲取 HTTP 代理的 URL。
此示例將預設的 ProxyHandler
替換為使用以程式設計方式提供的代理 URL 的處理程式,並使用 ProxyBasicAuthHandler
新增代理授權支援。
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
建構函式的 headers 引數,或者
import urllib.request
req = urllib.request.Request('http://www.example.com/')
req.add_header('Referer', 'https://python.club.tw/')
# Customize the default User-Agent header value:
req.add_header('User-Agent', 'urllib-example/0.1 (Contact: . . .)')
r = urllib.request.urlopen(req)
OpenerDirector
自動將 User-Agent 標頭新增到每個 Request
。要更改此行為,請執行以下操作
import urllib.request
opener = urllib.request.build_opener()
opener.addheaders = [('User-agent', 'Mozilla/5.0')]
opener.open('http://www.example.com/')
另外,請記住,當將 Request
傳遞給 urlopen()
(或 OpenerDirector.open()
) 時,會新增一些標準標頭 (Content-Length、Content-Type 和 Host)。
這是一個使用 GET
方法檢索包含引數的 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
方法。請注意,來自 urlencode 的 params 輸出在作為資料傳送到 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 代理,覆蓋環境設定
>>> import urllib.request
>>> proxies = {'http': 'http://proxy.example.com:8080/'}
>>> opener = urllib.request.FancyURLopener(proxies)
>>> with opener.open("https://python.club.tw") as f:
... f.read().decode('utf-8')
...
以下示例根本不使用代理,覆蓋環境設定
>>> import urllib.request
>>> opener = urllib.request.FancyURLopener({})
>>> with opener.open("https://python.club.tw/") as f:
... f.read().decode('utf-8')
...
舊介面¶
以下函式和類是從 Python 2 模組 urllib
(而不是 urllib2
)移植過來的。它們可能在未來的某個時候被棄用。
- urllib.request.urlretrieve(url, filename=None, reporthook=None, data=None)¶
將 URL 表示的網路物件複製到本地檔案。如果 URL 指向本地檔案,除非提供了 filename,否則不會複製該物件。返回一個元組
(filename, headers)
,其中 *filename* 是可以找到該物件的本地檔名,而 *headers* 是urlopen()
返回的物件(對於遠端物件)的info()
方法返回的內容。異常與urlopen()
相同。第二個引數(如果存在)指定要複製到的檔案位置(如果不存在,則該位置將是具有生成名稱的臨時檔案)。第三個引數(如果存在)是一個可呼叫物件,它將在建立網路連線時呼叫一次,然後在每次讀取塊後呼叫一次。該可呼叫物件將被傳遞三個引數:到目前為止傳輸的塊計數、以位元組為單位的塊大小以及檔案的總大小。在較舊的 FTP 伺服器上,第三個引數可能是
-1
,這些伺服器不返回檢索請求的檔案大小。以下示例說明了最常見的用法場景
>>> import urllib.request >>> local_filename, headers = urllib.request.urlretrieve('https://python.club.tw/') >>> html = open(local_filename) >>> html.close()
如果 *url* 使用
http:
方案識別符號,則可以提供可選的 *data* 引數來指定POST
請求(通常請求型別為GET
)。*data* 引數必須是標準 application/x-www-form-urlencoded 格式的位元組物件;請參閱urllib.parse.urlencode()
函式。當
urlretrieve()
檢測到可用資料量少於預期量(即 *Content-Length* 標頭報告的大小)時,將引發ContentTooShortError
。例如,當下載中斷時,可能會發生這種情況。*Content-Length* 被視為下限:如果有更多資料要讀取,則 urlretrieve 會讀取更多資料,但如果可用資料更少,則會引發異常。
在這種情況下,您仍然可以檢索下載的資料,它儲存在異常例項的
content
屬性中。如果沒有提供 *Content-Length* 標頭,urlretrieve 無法檢查其已下載的資料大小,只會返回資料。在這種情況下,您只需要假設下載成功即可。
- urllib.request.urlcleanup()¶
清除之前呼叫
urlretrieve()
可能留下的臨時檔案。
- class urllib.request.URLopener(proxies=None, **x509)¶
自版本 3.3 起棄用。
用於開啟和讀取 URL 的基類。除非您需要支援使用
http:
、ftp:
或file:
以外的方案開啟物件,否則您可能需要使用FancyURLopener
。預設情況下,
URLopener
類傳送一個 User-Agent 標頭,其值為urllib/VVV
,其中 *VVV* 是urllib
版本號。應用程式可以透過子類化URLopener
或FancyURLopener
,並在子類定義中將類屬性version
設定為適當的字串值來定義自己的 User-Agent 標頭。可選的 *proxies* 引數應該是一個字典,將方案名稱對映到代理 URL,其中空字典會完全關閉代理。其預設值為
None
,在這種情況下,如果存在環境代理設定,將使用該設定,如上面urlopen()
的定義中所討論的那樣。當使用
https:
方案時,收集在 *x509* 中的其他關鍵字引數可用於客戶端的身份驗證。支援關鍵字 *key_file* 和 *cert_file* 以提供 SSL 金鑰和證書;兩者都需要支援客戶端身份驗證。如果伺服器返回錯誤程式碼,
URLopener
物件將引發OSError
異常。- open(fullurl, data=None)¶
使用適當的協議開啟 *fullurl*。此方法設定快取和代理資訊,然後使用其輸入引數呼叫適當的 open 方法。如果方案無法識別,則呼叫
open_unknown()
。*data* 引數的含義與urlopen()
的 *data* 引數相同。此方法始終使用
quote()
對 *fullurl* 進行引用。
- open_unknown(fullurl, data=None)¶
可重寫的介面,用於開啟未知的 URL 型別。
- retrieve(url, filename=None, reporthook=None, data=None)¶
檢索 *url* 的內容並將其放置在 *filename* 中。返回值是一個元組,其中包含本地檔名和一個包含響應標頭的
email.message.Message
物件(對於遠端 URL)或None
(對於本地 URL)。然後,呼叫者必須開啟並讀取 *filename* 的內容。如果未給出 *filename* 並且 URL 指的是本地檔案,則返回輸入檔名。如果 URL 是非本地的並且未給出 *filename*,則檔名是tempfile.mktemp()
的輸出,其後綴與輸入 URL 的最後一個路徑元件的字尾匹配。如果給出了 *reporthook*,則它必須是一個接受三個數字引數的函式:塊號、讀取塊的最大大小以及下載的總大小(如果未知則為 -1)。它將在啟動時呼叫一次,並在每次從網路讀取資料塊後呼叫一次。對於本地 URL,*reporthook* 將被忽略。如果 *url* 使用
http:
方案識別符號,則可以提供可選的 *data* 引數來指定POST
請求(通常請求型別為GET
)。*data* 引數必須採用標準 application/x-www-form-urlencoded 格式;請參閱urllib.parse.urlencode()
函式。
- class urllib.request.FancyURLopener(...)¶
自版本 3.3 起棄用。
FancyURLopener
是URLopener
的子類,為以下 HTTP 響應程式碼提供預設處理:301、302、303、307 和 401。對於上面列出的 30x 響應程式碼,使用 Location 標頭來獲取實際的 URL。對於 401 響應程式碼(需要身份驗證),將執行基本 HTTP 身份驗證。對於 30x 響應程式碼,遞迴次數受 maxtries 屬性的值限制,預設為 10。對於所有其他響應程式碼,將呼叫方法
http_error_default()
,您可以在子類中重寫此方法以適當處理錯誤。注意
根據 RFC 2616 的規定,對 POST 請求的 301 和 302 響應在未經使用者確認的情況下不得自動重定向。實際上,瀏覽器允許自動重定向這些響應,將 POST 更改為 GET,並且
urllib
再現了此行為。建構函式的引數與
URLopener
的引數相同。注意
執行基本身份驗證時,
FancyURLopener
例項會呼叫其prompt_user_passwd()
方法。預設實現會在控制終端上要求使用者提供所需的資訊。如果需要,子類可以重寫此方法以支援更合適的行為。FancyURLopener
類提供了一個額外的方法,應該過載以提供適當的行為- prompt_user_passwd(host, realm)¶
返回在指定安全領域中對給定主機上的使用者進行身份驗證所需的資訊。返回值應為元組
(user, password)
,可用於基本身份驗證。該實現會在終端上提示此資訊;應用程式應重寫此方法,以便在本地環境中使用適當的互動模型。
urllib.request
限制¶
目前,僅支援以下協議:HTTP(版本 0.9 和 1.0)、FTP、本地檔案和資料 URL。
在 3.4 版本中更改: 增加了對資料 URL 的支援。
在有人找出時間正確處理過期時間標頭之前,已停用
urlretrieve()
的快取功能。應該有一個函式來查詢特定 URL 是否在快取中。
為了向後相容,如果 URL 看起來指向本地檔案但該檔案無法開啟,則會使用 FTP 協議重新解釋該 URL。這有時會導致令人困惑的錯誤訊息。
urlopen()
和urlretrieve()
函式可能會在等待建立網路連線時導致任意長時間的延遲。這意味著很難在不使用執行緒的情況下使用這些函式構建互動式 Web 客戶端。urlopen()
或urlretrieve()
返回的資料是伺服器返回的原始資料。這可能是二進位制資料(例如影像)、純文字或(例如)HTML。HTTP 協議在回覆標頭中提供型別資訊,可以透過檢視 Content-Type 標頭來檢查。如果返回的資料是 HTML,則可以使用模組html.parser
來解析它。處理 FTP 協議的程式碼無法區分檔案和目錄。當嘗試讀取指向不可訪問的檔案的 URL 時,這可能會導致意外的行為。如果 URL 以
/
結尾,則假定它引用一個目錄,並將相應地進行處理。但是,如果嘗試讀取檔案導致 550 錯誤(表示無法找到 URL 或無法訪問,通常是出於許可權原因),則該路徑將被視為目錄,以便處理透過 URL 指定目錄但省略了尾隨/
的情況。當您嘗試獲取讀取許可權使其無法訪問的檔案時,這可能會導致誤導性的結果;FTP 程式碼將嘗試讀取它,並因 550 錯誤而失敗,然後對不可讀取的檔案執行目錄列表。如果需要細粒度的控制,請考慮使用ftplib
模組,子類化FancyURLopener
,或更改 _urlopener 以滿足您的需求。
urllib.response
— urllib 使用的響應類¶
urllib.response
模組定義了函式和類,這些函式和類定義了最小的檔案式介面,包括 read()
和 readline()
。此模組定義的函式在內部被 urllib.request
模組使用。典型的響應物件是 urllib.response.addinfourl
例項