requests 讀取 cookies
import requests
from requests.cookies import RequestsCookieJar
s = requests.session()
s.verify = False
s.headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
}
s.get("http://www.baidu.com")
#這里我們使用cookie對象進(jìn)行處理
jar = RequestsCookieJar()
with open("cookies.txt", "r") as fp:
cookies = json.load(fp)
for cookie in cookies:
jar.set(cookie['name'], cookie['value'])
#百度個(gè)人中心
r = s.get("https://www.baidu.com/p/setting/profile/basic", cookies=jar)
# 也可以使用字典設(shè)置
cookies_dict = dict()
with open("cookies.txt", "r") as fp:
cookies = json.load(fp)
for cookie in cookies:
cookies_dict[cookie['name']] = cookie['value']
r = s.get("https://www.baidu.com/p/setting/profile/basic", cookies=cookies_dict)
r.encoding = "utf-8"
print(r.text)
requests 庫可以使用 cookies 對象和 dict 對象來指定 cookies分别,這個(gè)可以看一下源碼
通過 requests 讀取 cookies 的使用势篡,我們知道在 cookies 中我們一般只使用 name 和 value,像 domain盒让、path 等值都是不需要使用的,而且上面?zhèn)魅?cookies 字典的例子我們知道,只要保存了 cookies 中的 name 和 value背传,無論你以什么樣的方式保存剩盒,文件谷婆、或者數(shù)據(jù)庫等,最后讀取出來只要生成對應(yīng)的字典格式就行了辽聊。
requests 保存 cookies
import requests
s = requests.session()
s.verify = False
s.headers = {
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
}
# 這里可以是模擬登陸的步驟
s.get("http://www.baidu.com")
cookies = requests.utils.dict_from_cookiejar(s.cookies)
with open("cook.txt", "w") as fp:
json.dump(cookies, fp)
print(cookies)
首先我們看一下 requests.session 里面的 cookies纪挎,它是一個(gè) RequestsCookieJar 對象,這就是我們在上面使用的時(shí)候用 RequestsCookieJar 對象讀取 cookies 的原因了
下面我們看到 requests.utils.dict_from_cookiejar 方法跟匆,這是 requests 庫提供的一個(gè)方法异袄,把上面的 RequestsCookieJar 對象轉(zhuǎn)換為一個(gè)字典(字典里只有 name 和 value),這就是我上面說的玛臂,requests 庫只使用 name 和 value 值烤蜕,而我們 selenium 中保存的 cookies 中包含 domain、path 等信息迹冤。
另外還有一個(gè)方法 requests.utils.cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True) 這個(gè)方法讽营,根據(jù)字典生成一個(gè) RequestsCookieJar 對象,為什么需要這樣一個(gè)方法呢泡徙,可能在上面的應(yīng)用中有些人會有疑問橱鹏,我們的 cookies 是通過 get/post 方法的參數(shù)傳進(jìn)去的,那么在訪問其他網(wǎng)頁的時(shí)候都要去傳遞這樣一個(gè)參數(shù)嗎堪藐?這樣很不方便而且容易遺忘莉兰。看上圖的 s.cookies 變量礁竞,它是 requests.session 對象中的變量贮勃,而且是一個(gè) RequestsCookieJar 類型的對象,那么我們就可以使用這個(gè)函數(shù)把讀取的字典信息轉(zhuǎn)換為 RequestsCookieJar 對象苏章,然后把值直接設(shè)置給 s.cookies寂嘉,就像上面代碼里的 headers 一樣,這樣就方便很多了吧枫绅。
request 中保持 Cookies 一直有效
在使用 request 模塊寫爬蟲時(shí)泉孩,cookie 過一段時(shí)間便會自動(dòng)失效,這時(shí)爬蟲程序就無法繼續(xù)運(yùn)行并淋,讓人很是無奈寓搬。
我們知道,cookie 里面保存著我們的身份信息县耽,網(wǎng)站服務(wù)器通過 cookie 來識別我們的身份句喷,為了安全镣典,一般 cookie 都會有有效時(shí)間,過了這個(gè)時(shí)間唾琼,則 cookie 會自動(dòng)失效兄春,此時(shí),服務(wù)器便無法識別我們身份锡溯,這時(shí)如果我們請求一個(gè)需要登錄才能查看的資源赶舆,網(wǎng)站會自動(dòng)跳轉(zhuǎn)到登錄界面。
request 中提供了一個(gè)高級用法來解決這個(gè)問題:session
session 會話對象讓你能夠跨請求保持某些參數(shù)祭饭。它也會在同一個(gè) Session 實(shí)例發(fā)出的所有請求之間保持 cookies芜茵。
也就是 session 可以自動(dòng)更新請求時(shí)的 headers,但是事實(shí)很殘酷倡蝙,雖然我們使用了 session 對象九串,cookie 依舊會失效。
這是因?yàn)?session 確實(shí)會根據(jù)服務(wù)器響應(yīng)的信息自動(dòng)更新下次請求的 headers寺鸥,但是蒸辆,它并不是簡單的覆蓋原來的 headers,而是與程序中我們自己設(shè)置的原來的 headers 合并析既,而且,用戶設(shè)置的優(yōu)先度更高谆奥,也就是說眼坏,合并時(shí),新的 cookie 被丟棄了酸些,而我們設(shè)置的舊的 cookie 卻保留下來了宰译。所以程序中的 cookie 依舊會失效,因?yàn)?cookie 一直沒有更新嘛魄懂!
找到了問題出現(xiàn)的原因沿侈,也就找到了解決方法:請求后自行更新 cookie,代碼如下:
s = requests.session()
s.headers.update(headers)
r = s.get(url='https://www.arrow.com')
if r.cookies.get_dict():
s.cookies.update(r.cookies.get_dict())
print s.cookies
這樣 cookie 即可保持一直有效市栗。