[Python]網路爬蟲(三):使用cookiejar管理cookie 以及 模擬登入知乎
大家好哈,上一節我們研究了一下爬蟲的異常處理問題,那麼接下來我們一起來看一下Cookie的使用。
為什麼要使用Cookie呢?
Cookie,指某些網站為了辨別使用者身份、進行session跟蹤而儲存在使用者本地終端上的資料(通常經過加密)
比如說有些網站需要登入後才能訪問某個頁面,在登入之前,你想抓取某個頁面內容是不允許的。那麼我們可以利用python3的cookiejar模組來儲存cookie資訊,然後模擬登入。
在此之前呢,我們必須先介紹一個opener的概念。
1.Opener
當你獲取一個URL你使用一個opener。在前面,我們都是使用的預設的opener,也就是urlopen。它是一個特殊的opener,可以理解成opener的一個特殊例項,傳入的引數僅僅是url,data,timeout。
如果我們需要用到Cookie,只用這個opener是不能達到目的的,所以我們需要建立更一般的opener來實現對Cookie的設定。
2.Cookiejar
cookiejar模組的主要作用是提供可儲存cookie的物件,以便於與urllib模組配合使用來訪問Internet資源。Cookiejar模組非常強大,我們可以利用本模組的CookieJar類的物件來捕獲cookie並在後續連線請求時重新發送,比如可以實現模擬登入功能。該模組主要的物件有CookieJar、FileCookieJar、MozillaCookieJar、LWPCookieJar。
它們的關係:CookieJar —-派生—->FileCookieJar —-派生—–>MozillaCookieJar和LWPCookieJar
1)獲取Cookie儲存到變數
首先,我們先利用CookieJar物件實現獲取cookie的功能,儲存到變數中,先來感受一下
12345678910111213 | from urllib import requestfrom urllib import parsefrom http import cookiejar#宣告一個CookieJar物件例項來儲存cookiecookie=cookiejar.CookieJar()#利用urllib庫中的request的HTTPCookieProcessor物件來建立cookie處理器handler=request.HTTPCookieProcessor |
我們使用以上方法將cookie儲存到變數中,然後打印出了cookie中的值,執行結果如下
1 2 3 4 5 6 7 8 9 10 |
Name = BAIDUID Value = 5C63AF95C94F5EE96BC89EE5E9CE0188:FG=1 Name = BIDUPSID Value = 5C63AF95C94F5EE96BC89EE5E9CE0188 Name = H_PS_PSSID Value = 1431_24557_21123_24022_20928 Name = PSTM Value = 1508901974 Name = BDSVRTM Value = 0 Name = BD_HOME Value = 0 |
2)儲存Cookie到檔案
在上面的方法中,我們將cookie儲存到了cookie這個變數中,如果我們想將cookie儲存到檔案中該怎麼做呢?這時,我們就要用到
FileCookieJar這個物件了,建立LWPCookieJar例項,可以存Set-Cookie3型別的檔案。而MozillaCookieJar類是存為'.txt'格式的檔案.在這裡我們使用它的子類MozillaCookieJar來實現Cookie的儲存
123456789101112131415 | #!/usr/bin/env/python #encoding: UTF-8 from urllib import request from urllib import parse from http import cookiejar #設定儲存cookie的檔案,同級目錄下的cookie.txt filename = 'cookie.txt' #宣告一個MozillaCookieJar物件例項來儲存cookie,之後寫入檔案 cookie = cookiejar.MozillaCookieJar(filename) #利用urllib庫的HTTPCookieProcessor物件來建立cookie處理器 handler = request.HTTPCookieProcessor(cookie) #通過handler來構建opener opener = request.build_opener(handler) #建立一個請求,原理同urllib2的urlopen response = opener.open("http://www.baidu.com") #儲存cookie到檔案 cookie.save(ignore_discard=True, ignore_expires=True) |
關於最後save方法的兩個引數在此說明一下:
官方解釋如下:
ignore_discard: save even cookies set to be discarded.
ignore_expires: save even cookies that have expiredThe file is overwritten if it already exists
由此可見,ignore_discard的意思是即使cookies將被丟棄也將它儲存下來,ignore_expires的意思是如果在該檔案中cookies已經存在,則覆蓋原檔案寫入,在這裡,我們將這兩個全部設定為True。執行之後,cookies將被儲存到cookie.txt檔案中,我們檢視一下內容,附圖如下
使用LWPCookieJar來儲存cookie:
filename ='cookie'
cookie = cookiejar.LWPCookieJar(filename)
使用的時候直接load。
3)從檔案中獲取Cookie並訪問
那麼我們已經做到把Cookie儲存到檔案中了,如果以後想使用,可以利用下面的方法來讀取cookie並訪問網站,感受一下
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#!/usr/bin/env/python #encoding: UTF-8 from urllib import request from urllib import parse from http import cookiejar cookie = cookiejar.MozillaCookieJar() cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True) req= request.Request('http://www.baidu.com') opener = request.build_opener(request.HTTPCookieProcessor(cookie)) response = opener.open(req) print(response.read()) |
設想,如果我們的 cookie.txt 檔案中儲存的是某個人登入百度的cookie,那麼我們提取出這個cookie檔案內容,就可以用以上方法模擬這個人的賬號登入百度。
4)利用cookie模擬網站登入
下面我們以知乎為例,利用cookie實現模擬登入,來感受一下cookie大法吧!
#!/usr/bin/env/python
#encoding: UTF-8
import re
import requests
import http.cookiejar
from PIL import Image
import time
import json
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 '
'(KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36',
"Host": "www.zhihu.com",
"Referer": "https://www.zhihu.com/",
}
# 建立一個會話,可以把同一使用者的不同請求聯絡起來;直到會話結束都會自動處理cookies
session = requests.Session()
# 建立LWPCookieJar例項,可以存Set-Cookie3型別的檔案。
# 而MozillaCookieJar類是存為'/.txt'格式的檔案
session.cookies = http.cookiejar.LWPCookieJar("cookie")
# 若本地有cookie則不用再post資料了
try:
session.cookies.load(ignore_discard=True)
except IOError:
print('Cookie未載入!')
def get_xsrf():
"""
獲取引數_xsrf
"""
response = session.get('https://www.zhihu.com', headers=headers)
html = response.text
get_xsrf_pattern = re.compile(r'<input type="hidden" name="_xsrf" value="(.*?)"')
_xsrf = re.findall(get_xsrf_pattern, html)[0]
return _xsrf
def get_captcha():
"""
獲取驗證碼本地顯示
返回你輸入的驗證碼
"""
t = str(int(time.time() * 1000))
captcha_url = 'http://www.zhihu.com/captcha.gif?r=' + t + "&type=login"
response = session.get(captcha_url, headers=headers)
with open('cptcha.gif', 'wb') as f:
f.write(response.content)
# Pillow顯示驗證碼
im = Image.open('cptcha.gif')
im.show()
captcha = input('本次登入需要輸入驗證碼: ')
return captcha
def login(username, password):
"""
輸入自己的賬號密碼,模擬登入知乎
"""
# 檢測到11位數字則是手機登入
if re.match(r'\d{11}$', username):
url = 'http://www.zhihu.com/login/phone_num'
data = {'_xsrf': get_xsrf(),
'password': password,
'remember_me': 'true',
'phone_num': username
}
else:
url = 'https://www.zhihu.com/login/email'
data = {'_xsrf': get_xsrf(),
'password': password,
'remember_me': 'true',
'email': username
}
# 若不用驗證碼,直接登入
result = session.post(url, data=data, headers=headers)
# 列印返回的響應,r = 1代表響應失敗,msg裡是失敗的原因
# loads可以反序列化內建資料型別,而load可以從檔案讀取
if (json.loads(result.text))["r"] == 1:
# 要用驗證碼,post後登入
data['captcha'] = get_captcha()
result = session.post(url, data=data, headers=headers)
print((json.loads(result.text))['msg'])
# 儲存cookie到本地
session.cookies.save(ignore_discard=True, ignore_expires=True)
def isLogin():
# 通過檢視使用者個人資訊來判斷是否已經登入
url = "https://www.zhihu.com/settings/profile"
# 禁止重定向,否則登入失敗重定向到首頁也是響應200
login_code = session.get(url, headers=headers, allow_redirects=False).status_code
if login_code == 200:
return True
else:
return False
if __name__ == '__main__':
if isLogin():
print('您已經登入')
else:
account = input('輸入賬號:')
secret = input('輸入密碼:')
login(account, secret)
以上程式的原理如下
建立一個帶有cookie的opener,在訪問登入的URL時,將登入後的cookie儲存下來,然後利用這個cookie來訪問其他網址。
如登入之後才能檢視的成績查詢呀,本學期課表呀等等網址,模擬登入就這麼實現啦,是不是很酷炫?
好,小夥伴們要加油哦!我們現在可以順利獲取網站資訊了,接下來就是把網站裡面有效內容提取出來,下一節我們去會會正則表示式!