python3下urllib.request庫高級應用之Handle處理器和自定義Opener
經過前面對urllib.request庫的頻繁使用,都知道我們使用urllib庫請求是都是使用urlopen()方法實現的。實際上它的底層是使用HTTPHandler個Opener來實現的。查看urllib.request庫里的urlopen()方法的源碼。
def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,
*, cafile=None, capath=None, cadefault=False, context=None):
global _opener
if cafile or capath or cadefault:
if context is not None:
raise ValueError(
"You can't pass both context and any of cafile, capath, and "
"cadefault"
)
if not _have_ssl:
raise ValueError('SSL support not available')
context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH,
cafile=cafile,
capath=capath)
https_handler = HTTPSHandler(context=context)
opener = build_opener(https_handler)
elif context:
https_handler = HTTPSHandler(context=context)
opener = build_opener(https_handler)
elif _opener is None:
_opener = opener = build_opener()
else:
opener = _opener
return opener.open(url, data, timeout)
def install_opener(opener):
global _opener
_opener = opener_url_tempfiles = []
opener是 urllib.request.OpenerDirector 的實例,我們之前一直都在使用的urlopen,它是一個特殊的opener(也就是模塊幫我們構建好的)。
我們采用urlopen()的方式去請求,其實是有些局限性的,比如我們需要打開debug模式,或通過代理模式去請求,就不行了。如果要實現debug模式或代理請求的話,我們需要自己定義Handler和opener。
可以使用相關的 Handler處理器 來創建特定功能的處理器對象;
然后通過 urllib.request.build_opener()方法使用這些處理器對象,創建自定義opener對象;
使用自定義的opener對象,調用open()方法發送請求。
如果程序里所有的請求都使用自定義的opener,可以使用urllib.request.install_opener() 將自定義的 opener 對象 定義為 全局opener,表示如果之后凡是調用urlopen,都將使用這個opener(根據自己的需求來選擇)
在urllib庫中,給我們提供了一些Handler,如:HTTPHandler,HTTPSHandler,ProxyHandler,BaseHandler,AbstractHTTPHandler,FileHandler,FTPHandler,分別用於處理HTTP,HTTPS,Proxy代理等。
例子一: 簡單的自定義opener()
import urllib.request
# 第一步:構建一個HTTPHandler 處理器對象,支持處理HTTP請求
http_handler = urllib.request.HTTPHandler()
# 第二步:調用urllib2.build_opener()方法,創建支持處理HTTP請求的opener對象
opener = urllib.request.build_opener(http_handler)
# 第三步:構建 Request請求
request = urllib.request.Request("http://www.baidu.com/")
# 第四步:調用自定義opener對象的open()方法,發送request請求
response = opener.open(request)
# 第五步:獲取服務器響應內容
print(response.read())
程序運行的結果:
這種方式發送請求得到的結果,和使用urllib.request.urlopen()發送HTTP/HTTPS請求得到的結果是一樣的。
HTTPHandler的debug模式
HTTPHandler的debug模式,是通過在HTTPHandler的參數中傳入debuglevel=1,1表示打開debug模式。0表示關閉,默認是0。:
例子二:HTTPHandler的debug模式
import urllib.request
# 第一步:構建一個HTTPHandler 處理器對象,支持處理HTTP請求,同時開啟Debug Log
http_handler = urllib.request.HTTPHandler(debuglevel=1)
# 第二步:調用urllib2.build_opener()方法,創建支持處理HTTP請求的opener對象
opener = urllib.request.build_opener(http_handler)
# 第三步:構建 Request請求
request = urllib.request.Request("http://www.baidu.com/")
# 第四步:調用自定義opener對象的open()方法,發送request請求
response = opener.open(request)
# 第五步:獲取服務器響應內容
print(response.read().decode('utf-8'))
運行結果:
如果在 HTTPHandler()增加 debuglevel=1參數,就會將 Debug Log 打開,這樣程序在執行的時候,會把收包和發包的報頭在屏幕上自動打印出來,方便調試,有時可以省去抓包的工作。
---------------------
個人今日頭條賬號: 聽海8 (上面上傳了很多相關學習的視頻以及我書里的文章,大家想看視頻,可以關注我的今日頭條)