我們日常工作中,單純的HTTP請求,程序員都傾向於使用萬能的python Requests庫。但大多數場景下,我們的需求頁面不是純靜態網頁,網頁加載過程中伴隨有大量的JS文件參與頁面的整個渲染過程,且頁面的每一步操作可能都能找到異步加載XHR的影子。所以Requests庫不是萬能的,Requests-Html庫就能解決一部分問題,前提是您知道這個過程加載了哪些js文件。小爬的實際工作中,更傾向於Requests+selenium的模式來完成整個網頁信息的爬取。
能用Requests庫直接請求獲得數據的,就直接用requests的Session類來請求,碰到頁面中JS載入較多的,就切換到selenium來執行。
那么問題來了,如何從requests優雅地切換到selenium來完成整個網頁的自動化過程呢?很多時候,我們的頁面信息爬取,服務器都是要求用戶先登陸的,然后每次請求的時候保證會話session和基本cookies不變,就可以一直保證后台的登陸狀態。那么requests庫的cookies如何傳給selenium用呢?這樣切換到selenium時,我們不用再次登陸,而是直接用requests給的cookies綁定到 selenium下,請求目標網頁,打開的網頁就可以天然是登陸狀態了。
我們先使用requests庫來登陸,代碼通常是這樣(需要抓包看后台的post請求的data參數,我們請求前構造這個參數就可以了,每個網頁的登陸的data參數不盡相同):
loginData={'redirect':'','username':username,'password':psw} session = requests.Session() r=session.post('%sportal/u/a/login.do'%base_url,loginData)
完成這部操作后,我們可以通過Post請求的status_code是否等於200來判斷頁面是否成功登陸。一旦登陸成功,則我們的session請求該網站后續的網頁時,這個session就可以一直保持下去了。
接下來,我么要拿到requests登陸網站后的cookies,它是requests的Cookiejar類的一個實例。Cookiejar簡單來說就是獲取響應的cookie,cookie是存儲在瀏覽器的一些信息,包括用戶的登陸信息和一些操作,我們從服務器中獲取的響應信息中,有時候也會包含一些cookie信息。
問題是這個cookiejar對象不是我們常見的字典型cookies對象,我們需要利用requests庫的utils.dict_from_cookiejar方法來把cookiejar對象轉換為python的字典對象。
cookies=session.cookies
cookies=requests.utils.dict_from_cookiejar(cookies)
得到的cookies大概如下形式:
但是這依然不是selenium支持的cookies格式。實際上,selenium使用driver.get_cookies()方法得到的cookies如下:列表中包含多個cookie字典,每個字典中包含多個鍵值對,而所有的鍵中,有的不是必須的,但是“name","value"這兩個鍵是必填的。
"""傳遞request cookie給 selenium用""" for k,v in cookies.items(): driver.add_cookie({"name":k,"value":v})
需要注意的是,必須先要driver.get(your url),然后才能使用driver.add_cookie方法,否則selenium會報錯。
至此,我們的selenium就成功添加了requests中捕獲的響應的cookies,我們的selenium就不用再被服務器要求先登陸了。requests就和selenium完成了無縫銜接,完美!