筆記-python-urllib
筆記-python-urllib
1. 簡介
PYTHON3中將urllib,urllib2整合到URLLIB中
包括以下模塊
urllib.request 請求模塊(核心)
urllib.error 異常處理模塊
urllib.parse url解析模塊(主要用於url生成,格式處理)
urllib.robotparser robots.txt解析模塊
2. urllib.request
基本過程是構造handler ,opener,安裝opener,構造請求,使用urlopen執行請求;
2.1. handler
具體handler不詳細列出;常用的有
代理:
proxy = urllib.request.ProxyHandler({"http": proxy_addr[0]})
#使用http.cookiejar.CookieJar()創建CookieJar對象
cookie:
cjar=http.cookiejar.CookieJar()
#使用HTTPCookieProcessor創建cookie處理器,並以其為參數構建opener對象
cookie=urllib.request.HTTPCookieProcessor(cjar)
2.2. opner構造及使用
build_opener([handler,…])
返回一個OpenerDirector實例
本函數按參數中給定順序處理實例,參數可以是BaseHandler的實例或子類的實例;
下列類會最先處理實例,除非參數中包含它們或它們的子類: ProxyHandler ,
UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor.
實例:
上文構造了代理和cookie的handler
opener=urllib.request.build_opener(proxy)或
opener=urllib.request.build_opener(cookie)
安裝opener後便可以使用urlopen了;
urllib.request.install_opener(opener)
install_opener實際是將opener置為全局參數_opener
2.3. 構造請求Request
構造請求,上面部分定義了使用什麽來執行請求,下面將定義請求的內容:
class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
調用Request創建Request對象,調用urlopen傳入Request對象,返回一個相關請求response對象,這個應答對象如同一個文件對象;
2.3.1. data生成
data是一個字典,在使用前需要轉換成字節碼
test_data = {‘ServiceCode‘:‘aaaa‘,‘b‘:‘bbbbb‘}
test_data_urlencode = urllib.parse.urlencode(test_data)
2.4. urlopen
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
相當於opener通用版;
參數及特性:
返回對象:
對於http,https,返回一個http.client.HTTPResponse對象。
For FTP, file, and data URLs and requests explicitly handled by legacy URLopener and FancyURLopenerclasses, this function returns a urllib.response.addinfourl object.
對於返回對象,可以使用r.info() 、r.getcode() 、r.geturl()獲取相應的當前環境信息、狀態碼、當前網頁URL
urllib.request module uses HTTP/1.1
If context is specified, it must be a ssl.SSLContext instance describing the various SSL options. See HTTPSConnection for more details.
timeout 超時,如果不指定,使用默認
data決定是get還是post,但一般復雜一點的請求都使用Request函數了;
2.5. urlretrive
urlretrieve(url, filename=None, reporthook=None, data=None)
參數filename指定了保存本地路徑(如果參數未指定,urllib會生成一個臨時文件保存數據。)
參數reporthook是一個回調函數,當連接上服務器、以及相應的數據塊傳輸完畢時會觸發該回調,我們可以利用這個回調函數來顯示當前的下載進度。
reporthook實現代碼:if reporthook: reporthook(blocknum, bs, size)
參數data指post導服務器的數據,該方法返回一個包含兩個元素的(filename, headers) 元組,filename 表示保存到本地的路徑,header表示服務器的響應頭
def cbk(a,b,c):
per = 100.0*a*b/c
if per>100:
per=100
print("%.2f%%" % per)
url = "https://dzs.qisuu.la/34/34968/%E5%8F%B2%E4%B8%8A%E6%9C%80%E7%89%9B%E8%BD%AE%E5%9B%9E.txt"
urllib.request.urlretrieve(url, "b.txt",cbk)
該函數繼承於python2,python3.6.5文檔提及該函數以後可能作廢;
2.6. 其它函數
urllib.request.getproxies() 獲取代理參數
3. 使用
添加頭部,使用代理:
proxy = urllib.request.ProxyHandler({"http": proxy_addr[0]})
opener = urllib.request.build_opener(proxy)
urllib.request.install_opener(opener)
req = urllib.request.Request(self.proxy_verify_addr, headers=proxy_headers)
發送post請求:
postdata = urllib.parse.urlencode(post).encode(‘utf-8‘)
req = urllib.request.Request(url, postdata)
response = urllib.request.urlopen(req)
使用cookie:
主要流程:構建CookieJar()對象cjar,再使用HTTPCookieProcessor()處理器,處理cjar,並通過build_opener()構建opener對象,設置成全局,通過urlopen()發送請求。
註意:需要導入Cookie處理模塊http.cookiejar。
Import http.cookiejar
req=urllib.request.Request(url,postdata,headers=header)
#使用http.cookiejar.CookieJar()創建CookieJar對象
cjar=http.cookiejar.CookieJar()
#使用HTTPCookieProcessor創建cookie處理器,並以其為參數構建opener對象
cookie=urllib.request.HTTPCookieProcessor(cjar)
opener=urllib.request.build_opener(cookie)
#將opener安裝為全局
urllib.request.install_opener(opener)
reponse=urllib.request.urlopen(request)
4. 異常處理和http狀態碼
當urlopen不能夠處理一個response時,產生urlError。
不過通常的Python APIs異常如ValueError,TypeError等也會同時產生。
HTTPError是urlError的子類,通常在特定HTTP URLs中產生。
1. URLError
通常,URLError在沒有網絡連接(沒有路由到特定服務器),或者服務器不存在的情況下產生。
這種情況下,異常同樣會帶有"reason"屬性,它是一個tuple(可以理解為不可變的數組),包含了一個錯誤號和一個錯誤信息。
2. 服務器上每一個HTTP應答對象response包含一個數字狀態碼
典型錯誤包含404(頁面無法找到),403(請求禁止),401(帶驗證請求),成功200.
HTTP狀態碼通常分為5種類型,1-5數字開頭,由3位整數組成;
200:請求成功 處理方式:獲得響應的內容,進行處理
201:請求完成,結果是創建了新資源。新創建資源的URI可在響應的實體中得到 處理方式:爬蟲中不會遇到
202:請求被接受,但處理尚未完成 處理方式:阻塞等待
204:服務器端已經實現了請求,但是沒有返回新的信 息。如果客戶是用戶代理,則無須為此更新自身的文檔視圖。 處理方式:丟棄
300:該狀態碼不被HTTP/1.0的應用程序直接使用, 只是作為3XX類型回應的默認解釋。存在多個可用的被請求資源。 處理方式:若程序中能夠處理,則進行進一步處理,如果程序中不能處理,則丟棄
301:請求到的資源都會分配一個永久的URL,這樣就可以在將來通過該URL來訪問此資源 處理方式:重定向到分配的URL
302:請求到的資源在一個不同的URL處臨時保存 處理方式:重定向到臨時的URL
304 請求的資源未更新 處理方式:丟棄
400 非法請求 處理方式:丟棄
401 未授權 處理方式:丟棄
403 禁止 處理方式:丟棄
404 沒有找到 處理方式:丟棄
5XX 回應代碼以“5”開頭的狀態碼表示服務器端發現自己出現錯誤,不能繼續執行請求 處理方式:丟棄
5. 附錄
在Python2.X中,分urllib和urllib2,但在Python3.X中,都統一合並到urllib中。通過下表可以看到其中常見的變動;
相對來說,Python3.X對中文的支持比Python2.X友好。
urllib庫對照速查表
Python2.X |
Python3.X |
urllib |
urllib.request, urllib.error, urllib.parse |
urllib2 |
urllib.request, urllib.error |
urllib2.urlopen |
urllib.request.urlopen |
urllib.urlencode |
urllib.parse.urlencode |
urllib.quote |
urllib.request.quote |
urllib2.Request |
urllib.request.Request |
urlparse |
urllib.parse |
urllib.urlretrieve |
urllib.request.urlretrieve |
urllib2.URLError |
urllib.error.URLError |
cookielib.CookieJar |
http.CookieJar |
筆記-python-urllib