requests登录知乎新版

#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版权协议,转载请附上原文出处链接和本声明。