【前言】介紹一下項目模擬登陸和session以及csrf解決方案
一、驗證碼模擬登陸
1、前兩天實現的基於webdriver的,彈出登錄界面,截取驗證碼的方案被否決,因為服務器是沒有圖形界面的。所以,還是得從模擬登陸界面保持的角度去解決這個問題。期貨中心的網站防爬性是非常高的。需要注入token;最讓我頭疼是,還有一個url固定,隨機刷新的驗證碼。導致無法從get()的網頁上的驗證碼地址下載到和token一起發過來的驗證碼。每次解析地址將驗證碼寫入到png圖片時,都是刷新后的另一個驗證碼。錯誤代碼如下:
1 Img2 = re.compile(r'img id="imgVeriCode" src="/(.*?)"/>') 2 imgurl_1 = re.findall(Img2, r2) 3 imgurl= 'https://investorservice.cfmmc.com/'+imgurl_1[0] 4 imgbuf = s.get(imgurl,headers=bef_headers) #得不到真正的驗證碼,因為一個驗證碼url對應很多隨機驗證碼,每次解析獲取相當於刷新一次
5 with open("captcha.png","wb") as f: 6 f.write(imgbuf.content)
驗證碼地址:https://investorservice.cfmmc.com/veriCode.do?t=1532349129376
2、無論保持session還是攜帶cookie,都無發避免要輸入一次驗證碼,才能登陸上去。可是怎么獲取正確的驗證碼呢?
其實,還是對瀏覽器和服務器之間的通信機制不清楚。這是瀏覽器緩存機制,我可以發現驗證碼最后是一個時間戳(t=...)。所以,要得到緩存里沒有的驗證碼,最新的驗證碼,如果驗證碼url是從網頁分析出來的,其實這個url已經存在瀏覽器緩存里面了,get()不會向服務器請求,那怎么得到imgbuf呢?。加上時間戳,就解決了,其實可以看到即使在驗證碼url里去掉時間戳那一段,也可以請求到驗證碼。有人說加隨機數也可以,我沒試。核心就是不讓瀏覽器去緩存中去取。
1 s = requests.Session() 2 headers = {"User-Agent":"Mozilla/5.0"} 3 r = s.get("https://investorservice.cfmmc.com/login.do") 4 value = re.findall(r'name="org.apache.struts.taglib.html.TOKEN" value="(.*?)"',r.text)[0] 5 captcha = s.get("https://investorservice.cfmmc.com/veriCode.do?t={}".format(str(int(time.time()))), headers=headers) 6 with open("captcha.png","wb") as f: 7 f.write(captcha.content) 8 user_name='huangfuyuan' 9 passwd = 'xbxxxdx' 10 vericode = yanzheng_local() #ocr深度學習識別方法 11 print vericode 12 data = { 13 "org.apache.struts.taglib.html.TOKEN":value, 14 "showSaveCookies":"hfy", 15 "userID":user_name, 16 "password":passwd, 17 "vericode":vericode, 18 } 19 login = s.post("https://investorservice.cfmmc.com/login.do", headers=headers, data=data) 20 #返回值是一個respond的對象,s已經保持登錄了 21 new_url=s.get("https://investorservice.cfmmc.com/customer/setupViewCustomerDetailFromCompanyAuto.do") 22 print new_url.url 23 #print(new_url.text) 24 while new_url.url!="https://investorservice.cfmmc.com/customer/setupViewCustomerDetailFromCompanyAuto.do": 25 print "驗證碼沒有識別正確,請重新啟動" 26 exit(0)
要加深對瀏覽器前端的學習,我不是干這個的,淺嘗輒止吧!完美解決“python驗證碼保持登錄遇到動態驗證碼問題”。
二、session保持登錄
從返回的cookie來看,里面有jessionid,是一種集群的tomcat服務器。里面可能有nginx反向代理服務器,這對我們透明不必在意。所以,他的分布式session解決方案是每次訪問攜帶jessionid。當然還有很多方法解決分布式session,例如session服務器,可參考我。
三、token解決csrf
爬區網頁token,登錄攜帶。
value = re.findall(r'name="org.apache.struts.taglib.html.TOKEN" value="(.*?)"',r.text)[0]
————2018.7.23 23.32深圳平山村的出租屋。