Handler處理器 和 Opener 及Cookie

Roc Huang發表於2020-09-24

Handler處理器 和 自定義Opener

opener是 urllib2.OpenerDirector 的例項,我們之前一直都在使用的urlopen,它是一個特殊的opener(也就是模組幫我們構建好的)。

但是基本的urlopen()方法不支援代理、cookie等其他的HTTP/HTTPS高階功能。所以要支援這些功能:
1、使用相關的Handler處理器來建立特定功能的處理器物件;
2、然後通過urllib2.build_opener()方法使用這些處理器物件,建立自定義opener物件;
3、使用自定義的opener物件,呼叫open()方法傳送請求。

如果程式裡所有的請求都使用自定義的opener,可以使用urllib2.install_opener()將自定義的 opener 物件 定義為 全域性opener,表示如果之後凡是呼叫urlopen,都將使用這個opener(根據自己的需求來選擇)

簡單的自定義opener()

import urllib
from urllib import request

# 構建一個HTTPHandler 處理器物件,支援處理HTTP請求
handler = urllib.request.HTTPHandler()  # http

# 構建一個HTTPHandler 處理器物件,支援處理HTTPS請求
# handlers = urllib.request.HTTPSHandler()  # 處理https的處理器

# 呼叫urllib2.build_opener()方法,建立支援處理HTTP請求的opener物件
opener = urllib.request.build_opener(handler)

# 構建 Request請求
req = urllib.request.Request("http://www.baidu.com", headers=headers)

# 呼叫自定義opener物件的open()方法,傳送request請求
response = opener.open(req)

# 獲取伺服器響應內容
print(response.read())
如果在 HTTPHandler()增加 debuglevel=1引數,還會將 Debug Log 開啟,這樣程式在執行的時候,會把收包和發包的報頭在螢幕上自動列印出來,方便除錯,有時可以省去抓包的工作

# 僅需要修改的程式碼部分:

# 構建一個HTTPHandler 處理器物件,支援處理HTTP請求,同時開啟Debug Log,debuglevel 值預設 0
http_handler = urllib2.HTTPHandler(debuglevel=1)

# 構建一個HTTPSHandler 處理器物件,支援處理HTTPS請求,同時開啟Debug Log,debuglevel 值預設 0
https_handler = urllib2.HTTPSHandler(debuglevel=1)

Cookie

Cookie 是指某些網站伺服器為了辨別使用者身份和進行Session跟蹤,而儲存在使用者瀏覽器上的文字檔案,Cookie可以保持登入資訊到使用者下次與伺服器的會話。

Cookie原理

HTTP是無狀態的協議, 為了保持連線狀態, 引入了Cookie機制 Cookie是http訊息頭中的一種屬性,包括:
Cookie名字(Name)
Cookie的值(Value)
Cookie的過期時間(Expires/Max-Age)
Cookie作用路徑(Path)
Cookie所在域名(Domain),
使用Cookie進行安全連線(Secure)。

前兩個引數是Cookie應用的必要條件,另外,還包括Cookie大小(Size,不同瀏覽器對Cookie個數及大小限制是有差異的)。

Cookie由變數名和值組成,根據 Netscape公司的規定,Cookie格式如下:
Set-Cookie: NAME=VALUE;Expires=DATE;Path=PATH;Domain=DOMAIN_NAME;SECURE

Cookie應用

Cookies在爬蟲方面最典型的應用是判定註冊使用者是否已經登入網站,使用者可能會得到提示,是否在下一次進入此網站時保留使用者資訊以便簡化登入手續。

cookielib庫 和 HTTPCookieProcessor處理器
在Python處理Cookie,一般是通過cookielib模組和 urllib2模組的HTTPCookieProcessor處理器類一起使用。

cookielib模組:主要作用是提供用於儲存cookie的物件

HTTPCookieProcessor處理器:主要作用是處理這些cookie物件,並構建handler物件。

cookielib 庫
該模組主要的物件有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。

CookieJar:管理HTTP cookie值、儲存HTTP請求生成的cookie、向傳出的HTTP請求新增cookie的物件。整個cookie都儲存在記憶體中,對CookieJar例項進行垃圾回收後cookie也將丟失。

FileCookieJar (filename,delayload=None,policy=None):從CookieJar派生而來,用來建立FileCookieJar例項,檢索cookie資訊並將cookie儲存到檔案中。filename是儲存cookie的檔名。delayload為True時支援延遲訪問訪問檔案,即只有在需要時才讀取檔案或在檔案中儲存資料。

MozillaCookieJar (filename,delayload=None,policy=None):從FileCookieJar派生而來,建立與Mozilla瀏覽器 cookies.txt相容的FileCookieJar例項。

LWPCookieJar (filename,delayload=None,policy=None):從FileCookieJar派生而來,建立與libwww-perl標準的 Set-Cookie3 檔案格式相容的FileCookieJar例項。

其實大多數情況下,我們只用CookieJar(),如果需要和本地檔案互動,就用 MozillaCookjar() 或 LWPCookieJar()

Cookie案例:

1.獲取Cookie
import urllib.request
from http import cookiejar  # python3
# import cookiejar  # python2

# 建立一個物件儲存cookie
cookies = cookiejar.LWPCookieJar()
# cookie處理器, 提取cookie
cookie_handler = urllib.request.HTTPCookieProcessor(cookies)
# 建立開啟器, 處理cookie
opener = urllib.request.build_opener(cookie_handler)

# 使用opener開啟url
response = opener.open("http://www.baidu.com/")
# 得到cookies
print(cookies)

  1. 下載cookie
import urllib.request
from http import cookiejar

filename = "baiducookie.txt"  # 用於儲存cookie
# 管理cookie的物件
cookies = cookiejar.LWPCookieJar(filename=filename)
# 建立cookie處理器
cookie_handler = urllib.request.HTTPCookieProcessor(cookies)
# 建立開啟器
opener = urllib.request.build_opener(cookie_handler)

# 新增UA,並開啟百度,下載cookie
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}

req = urllib.request.Request("http://www.baidu.com", headers=headers)

# 開啟
response = opener.open(req)

# 儲存, 忽略錯誤
cookies.save(ignore_discard=True, ignore_expires=True)

  1. 使用下載的cookie
import urllib.request
from http import cookiejar

filename = "baiducookie.txt"
cookies = cookiejar.LWPCookieJar()

# 使用cookie
cookies.load(filename)

cookie_handler = urllib.request.HTTPCookieProcessor(cookies)
opener = urllib.request.build_opener(cookie_handler)

# 新增UA,並開啟百度
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36"
}

req = urllib.request.Request("http://www.baidu.com", headers=headers)
response = opener.open(req)

HTTP響應狀態碼參考

1xx:資訊

100 Continue
	伺服器僅接收到部分請求,但是一旦伺服器並沒有拒絕該請求,客戶端應該繼續傳送其餘的請求。
101 Switching Protocols
	伺服器轉換協議:伺服器將遵從客戶的請求轉換到另外一種協議。


2xx:成功

200 OK
	請求成功(其後是對GET和POST請求的應答文件)
201 Created
	請求被建立完成,同時新的資源被建立。
202 Accepted
	供處理的請求已被接受,但是處理未完成。
203 Non-authoritative Information
	文件已經正常地返回,但一些應答頭可能不正確,因為使用的是文件的拷貝。
204 No Content
	沒有新文件。瀏覽器應該繼續顯示原來的文件。如果使用者定期地重新整理頁面,而Servlet可以確定使用者文件足夠新,這個狀態程式碼是很有用的。
205 Reset Content
	沒有新文件。但瀏覽器應該重置它所顯示的內容。用來強制瀏覽器清除表單輸入內容。
206 Partial Content
	客戶傳送了一個帶有Range頭的GET請求,伺服器完成了它。


3xx:重定向

300 Multiple Choices
	多重選擇。連結列表。使用者可以選擇某連結到達目的地。最多允許五個地址。
301 Moved Permanently
	所請求的頁面已經轉移至新的url。
302 Moved Temporarily
	所請求的頁面已經臨時轉移至新的url。
303 See Other
	所請求的頁面可在別的url下被找到。
304 Not Modified
	未按預期修改文件。客戶端有緩衝的文件併發出了一個條件性的請求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文件)。伺服器告訴客戶,原來緩衝的文件還可以繼續使用。
305 Use Proxy
	客戶請求的文件應該通過Location頭所指明的代理伺服器提取。
306 Unused
	此程式碼被用於前一版本。目前已不再使用,但是程式碼依然被保留。
307 Temporary Redirect
	被請求的頁面已經臨時移至新的url。


4xx:客戶端錯誤

400 Bad Request
	伺服器未能理解請求。
401 Unauthorized
	被請求的頁面需要使用者名稱和密碼。
401.1
	登入失敗。
401.2
	伺服器配置導致登入失敗。
401.3
	由於 ACL 對資源的限制而未獲得授權。
401.4
	篩選器授權失敗。
401.5
	ISAPI/CGI 應用程式授權失敗。
401.7
	訪問被 Web 伺服器上的 URL 授權策略拒絕。這個錯誤程式碼為 IIS 6.0 所專用。
402 Payment Required
	此程式碼尚無法使用。
403 Forbidden
	對被請求頁面的訪問被禁止。
403.1
	執行訪問被禁止。
403.2
	讀訪問被禁止。
403.3
	寫訪問被禁止。
403.4
	要求 SSL。
403.5
	要求 SSL 128403.6
	IP 地址被拒絕。
403.7
	要求客戶端證照。
403.8
	站點訪問被拒絕。
403.9
	使用者數過多。
403.10
	配置無效。
403.11
	密碼更改。
403.12
	拒絕訪問對映表。
403.13
	客戶端證照被吊銷。
403.14
	拒絕目錄列表。
403.15
	超出客戶端訪問許可。
403.16
	客戶端證照不受信任或無效。
403.17
	客戶端證照已過期或尚未生效。
403.18
	在當前的應用程式池中不能執行所請求的 URL。這個錯誤程式碼為 IIS 6.0 所專用。
403.19
	不能為這個應用程式池中的客戶端執行 CGI。這個錯誤程式碼為 IIS 6.0 所專用。
403.20
	Passport 登入失敗。這個錯誤程式碼為 IIS 6.0 所專用。
404 Not Found
	伺服器無法找到被請求的頁面。
404.0
	沒有找到檔案或目錄。
404.1
	無法在所請求的埠上訪問 Web 站點。
404.2
	Web 服務擴充套件鎖定策略阻止本請求。
404.3
	MIME 對映策略阻止本請求。
405 Method Not Allowed
	請求中指定的方法不被允許。
406 Not Acceptable
	伺服器生成的響應無法被客戶端所接受。
407 Proxy Authentication Required
	使用者必須首先使用代理伺服器進行驗證,這樣請求才會被處理。
408 Request Timeout
	請求超出了伺服器的等待時間。
409 Conflict
	由於衝突,請求無法被完成。
410 Gone
	被請求的頁面不可用。
411 Length Required
	"Content-Length" 未被定義。如果無此內容,伺服器不會接受請求。
412 Precondition Failed
	請求中的前提條件被伺服器評估為失敗。
413 Request Entity Too Large
	由於所請求的實體的太大,伺服器不會接受請求。
414 Request-url Too Long
	由於url太長,伺服器不會接受請求。當post請求被轉換為帶有很長的查詢資訊的get請求時,就會發生這種情況。
415 Unsupported Media Type
	由於媒介型別不被支援,伺服器不會接受請求。
416 Requested Range Not Satisfiable
	伺服器不能滿足客戶在請求中指定的Range頭。
417 Expectation Failed
	執行失敗。
423
	鎖定的錯誤。


5xx:伺服器錯誤

500 Internal Server Error
	請求未完成。伺服器遇到不可預知的情況。
500.12
	應用程式正忙於在 Web 伺服器上重新啟動。
500.13
	Web 伺服器太忙。
500.15
	不允許直接請求 Global.asa。
500.16
	UNC 授權憑據不正確。這個錯誤程式碼為 IIS 6.0 所專用。
500.18
	URL 授權儲存不能開啟。這個錯誤程式碼為 IIS 6.0 所專用。
500.100
	內部 ASP 錯誤。
501 Not Implemented
	請求未完成。伺服器不支援所請求的功能。
502 Bad Gateway
	請求未完成。伺服器從上游伺服器收到一個無效的響應。
502.1
	CGI 應用程式超時。 ·
502.2
	CGI 應用程式出錯。
503 Service Unavailable
	請求未完成。伺服器臨時過載或當機。
504 Gateway Timeout
	閘道器超時。
505 HTTP Version Not Supported
	伺服器不支援請求中指明的HTTP協議版本

相關文章