#coding:utf-8 #__author__='wang' import time,json,base64 ''' requests登陆知乎流程: requests登录知乎流程: 1>想到去抓包,查看用户名,密码表单数据的提交地址,也就是POST请求将表单数据提交的地址。 经过查看是:https://www.zhihu.com/api/v3/oauth/sign_in。 2>通过抓取上述登录地址,在其请求的Content字段中,发现POST到服务器的地址不只包含用户名 ,密码,还有timestamp, lang, client_id, signature等表单数据。所以,需要知道每 一个表单数据的特点,而特点我们从数据在每次登录时是否变化来查找数据的规律。 3>经过多次登录的观察,这些表单数据中,只有timestamp,signature是变化的,其它的值 都是不变的。 4>通过JS发现signature字段的值,是由多个字段组合加密而成,其实timestamp时间戳是核心 ,每次根据时间戳的变化,生成不同的signature值。 5>考虑到signature的加密过程较为复杂,所以直接将浏览器登录成功后的时间戳timestamp 和签名signature复制到请求数据中,然后进行登录。 6>表单数据填充完毕,发送POST请求时,出现了"缺少验证码票据的错误(capsion_ticket)", 经过分析,验证码票据是为获取验证码而提供的一种验证方式,而抓包工具中关于验证码的请求有 两次。一次获取的是:{'show_captcha': true},而同时请求的第二次获取的是: {'img_base64': 'Rfadausifupoauerfae'}。 7>经过分析,{'show_captcha': true}是获取验证码的关键信息,在抓包信息中,发现第一次 请求的响应中的Set-Cookie中,包含了capsion_ticket验证码票据信息。 8>再次模拟登录,又出现了"ERR_XX_AUTH_TOKEN"错误信息,而它出现在我们根据验证码票据获 取验证码图片时。我们从抓包信息中,查看关于captcha?lang=cn的请求信息,发现在请求头中 有这样一个字段:Authorization: oauth ce30dasjfldhjfadsfasdfad。所以将其在 headers中进行配置。 ''' import requests try: import cookielib except Exception,e: import http.cookiejar as cookielib session =requests.Session() session.cookies= cookielib.LWPCookieJar(filename = 'requests_coo.txt') try: session.cookies.load(ignore_discard=True,ignore_expires=True) print 'cookie信息加载成功' except Exception,e: print "cookie信息加载失败" headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0','HOST':'www.zhihu.com','Referer': 'https://www.zhihu.com/signin?next=%2F','Authorization': 'oauth c3cef7c66a1843f8b3a9e6a1e3160e20'} def zhihu_login(account,password,captcha): #登陆之前先拿验证码数据 # is_captcha = parse_captcha() # if is_captcha: # print '你有验证码,我不登陆' # # is_captcha =parse_captcha() # else: # print '没有验证码,我登陆' post_url='https://www.zhihu.com/api/v3/oauth/sign_in' post_data={ 'client_id':'c3cef7c66a1843f8b3a9e6a1e3160e20', 'grant_type':'password', 'timestamp':'1515398025518', 'source':'com.zhihu.web', 'signature':'30b129980d00e5efb09f16b0334bf4e8601b060b', 'username':account, 'password':password, 'captcha':captcha, 'lang':'en', 'ref_source':'homepage', 'utm_source':'' } response = session.post(post_url,data=post_data,headers= headers,verify=False) session.cookies.save(ignore_expires=True,ignore_discard=True) #如果直接登录会报一个异常“缺少验证码票据”,而验证码票据的获取是通过向 https://www.zhihu.com/api/v3/oauth/captcha?lang=cn地址发送get请求之后, 服务器会将验证码票据放入set-cookie中进行返回 def parse_captcha(): response = session.get('https://www.zhihu.com/api/v3/oauth/ captcha?lang=en',headers=headers,verify= False) show_captcha=response.json()['show_captcha'] if show_captcha: print '有验证码' #有验证码,就再一次向https://www.zhihu.com/api/v3/oauth/captcha ?lang=en发送put请求,用于向服务器索引当前的验证码的图片地址 response = session.put('https://www.zhihu.com/api/v3/oauth/ captcha?lang=en',headers=headers,verify=False) try: img=json.loads(response.content)['img_base64'] except Exception,e: print '获取img_base64的值失败,原因:'%e else: print '成功获取加密后的图片地址' #将加密后的图片进行解密,同时保存到本地 img = img.encode('utf-8') img_data = base64.b64decode(img) with open('zhihu_captcha.GIF','wb') as f: f.write(img_data) captcha = raw_input('请输入识别的验证码:') #将验证码继续发送post请求和服务器端进行对比是否正确 data = {'input_text':captcha} response = session.post('https://www.zhihu.com/api/v3/oauth/ captcha?lang=en',data = data,headers=headers,verify=False) try: yanzheng_result = json.loads(response.content)['success'] except Exception,e: print '关于验证码的post请求响应失败,原因:{}'.format(e) else: if yanzheng_result: zhihu_login('****','*****,captcha) else: print '是错误的验证码' # return True else: print '没有验证码' zhihu_login('*****','******',captcha='') parse_captcha() #SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed(_ssl.c:661))requests库在访问http://协议时,由于证书认证失败, 无法访问相应的服务这个时候可以通过verify=False设置禁止证书认证的过程。urllib2 在访问https://的时候也会只有这种异常出现 # zhihu_login('15518325965','yun0101@.29') def get_index_page(): response = session.get('https://www.zhihu.com',headers=headers, verify = False) with open('index.html','w') as f: f.write(response.content) print '获取信息成功' # get_index_page()
版权声明:本文为y15518325965原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。