浏览器模拟登录验证码及其缓存----项目小结

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

原文地址:https://www.cnblogs.com/huangfuyuan/p/9356747.html