在之前的文章中我們介紹了一下 opener 應用中的 ProxyHandler 處理器(代理設定),本篇文章我們再來看一下 opener 中的 Cookie 的使用。
Cookie 是指某些網站伺服器為了辨識使用者身份和進行Session跟蹤,而儲存在使用者浏覽器上的文本檔案,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在爬蟲方面最典型的應用是判定注冊使用者是否已經登入網站,使用者可能會得到提示,是否在下一次進入此網站時保留使用者資訊以便簡化登入手續。
1 import urllib.request
2
3 # 1. 建構一個已經登入過的使用者的headers資訊
4 headers = {
5 "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36",
6 "Cookie": "anonymid=jurpmxe9-orl7u3;"
7 "depovince=BJ;"
8 " _r01_=1; "
9 "JSESSIONID=abcwYLyIY7VNIhCDVWcPw;"
10 " jebe_key=f6fb270b-d06d-42e6-8b53-e67c3156aa7e%7Cc13c37f53bca9e1e7132d4b58ce00fa3%7C1484060607478%7C1%7C1484060607173;"
11 " jebecookies=f1fd29c4-bd08-4d66-8834-72e42b70d2cb|||||; "
12 "ick_login=0f790ea2-c8bf-4d64-a394-36745febeb26;"
13 " _de=622DE758381206EB340E4CEC836F3769696BF75400CE19CC;"
14 " p=7e50f3fe10ca320e36dae001c72d392d3;"
15 " ap=327550029;"
16 " first_login_flag=1;"
17 " [email protected];"
18 " ln_hurl=http://hdn.xnimg.cn/photos/hdn121/20120930/2035/h_main_hcDy_40fc000002d91375.jpg;"
19 " t=d7c6ae064b81ae15f5b91f5897dc61553;"
20 " societyguester=d7c6ae064b81ae15f5b91f5897dc61553;"
21 " id=485439163;"
22 " xnsid=bc995dc8;"
23 " ver=7.0;"
24 " loginfrom=null"
25 }
26
27 # 2. 通過headers裡的報頭資訊(主要是Cookie資訊),建構Request對象
28 request = urllib.request.Request("http://www.renren.com", headers=headers)
29
30 # 3. 直接通路renren首頁,伺服器會根據headers報頭資訊(主要是Cookie資訊),判斷這是一個已經登入的使用者,并傳回相應的頁面
31 response = urllib.request.urlopen(request)
32
33 # 4. 列印響應内容
34 print(response.read().decode("utf-8"))
但是這樣做太過複雜,我們先需要在浏覽器登入賬戶,并且設定儲存密碼,并且通過抓包才能擷取這個Cookie,那有麼有更簡單友善的方法呢?
cookielib庫 和 HTTPCookieProcessor處理器
在Python處理Cookie,一般是通過 http 子產品的 cookiejar 子產品和 urllib 子產品的
HTTPCookieProcessor
處理器類一起使用。
子產品:主要作用是提供用于存儲cookie的對象
cookiejar
處理器:主要作用是處理這些cookie對象,并建構handler對象。
HTTPCookieProcessor
1 import urllib.request
2 import urllib.parse
3 from http import cookiejar
4
5 # 1. 建構一個CookieJar對象執行個體來儲存cookie
6 cookie = cookiejar.CookieJar()
7
8 # 2. 使用HTTPCookieProcessor()來建立cookie處理器對象,參數為CookieJar()對象
9 cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
10
11 # 3. 通過 build_opener() 來建構opener
12 opener = urllib.request.build_opener(cookie_handler)
13
14 # 4. addheaders 接受一個清單,裡面每個元素都是一個headers資訊的元祖, opener将附帶headers資訊
15 opener.addheaders = [("User-Agent",
16 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36")]
17
18 # 5. 需要登入的賬戶和密碼
19 data = {"email": "[email protected]", "password": "chen562352353"}
20
21 # 6. 通過urlencode()轉碼
22 postdata = urllib.parse.urlencode(data).encode("utf-8")
23
24 # 7. 建構Request請求對象,包含需要發送的使用者名和密碼
25 request = urllib.request.Request("http://www.renren.com/PLogin.do", data=postdata)
26
27 # 8. 通過opener發送這個請求,并擷取登入後的Cookie值,
28 opener.open(request)
29
30 # 9. opener包含使用者登入後的Cookie值,可以直接通路那些登入後才可以通路的頁面
31 response = opener.open("http://www.renren.com/485439163")
32
33 # 10. 列印響應内容
34 print(response.read().decode("utf-8"))
模拟登入要注意幾點:
- 登入一般都會先有一個HTTP GET,用于拉取一些資訊及獲得Cookie,然後再HTTP POST登入。
- HTTP POST登入的連結有可能是動态的,從GET傳回的資訊中擷取。
- password 有些是明文發送,有些是加密後發送。有些網站甚至采用動态加密的,同時包括了很多其他資料的加密資訊,隻能通過檢視JS源碼獲得加密算法,再去破解加密,非常困難。
- 大多數網站的登入整體流程是類似的,可能有些細節不一樣,是以不能保證其他網站登入成功。