【前言】介绍一下项目模拟登陆和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深圳平山村的出租屋。