爬虫抓包模拟登陆新浪微博获取cookies

模拟登陆就是获取新浪服务器返回的登陆参数(cookies等),然后添加到爬虫的post请求中来伪装用户提交给新浪访客系统

首先感谢 Bgods(https://blog.csdn.net/songzhilian22/article/details/48396545

敲代码的耗子(http://www.cnblogs.com/mouse-coder/archive/2013/03/03/2941265.html?utm_source=tuicool)等前辈的启发

所需工具:chrome

python库:requests, re,rsa,binascii,  base64, urllib

一.分析新浪微博登陆机制

首先打开新浪通行证http://login.sina.com.cn/

然后打开chrome开发者工具Network页面 勾选 Preserve log 监控登陆过程

输入账户密码登陆(要记得提前清理浏览器Cookies)

可以观察到登陆过程中浏览器发出的请求

主要分析这三个请求

分别观察三个请求的Response_headers 和Cookies可以发现是在第二个请求中set的cookies

所以只要模拟了第二个请求就能拿到cookies

二.模拟登陆

PC登录新浪微博时,在客户端用js预先对用户名、密码都进行了加密,而且在POST之前会GET一组参数,这也将作为POST_DATA的一部分.

2.1GET获取四个参数(servertime,nonce,pubkey和rsakv)

username = '11111111'.encode()           #str 转bytes

    url = 'https://login.sina.com.cn/sso/prelogin.php?entry=account&callback=sinaSSOController.preloginCallBack&su={}&rsakt=mod&client=ssologin.js(v1.4.15)&_={}'.format(quote(username),quote(username))

 构造出url后GET获取四个参数servertime,nonce,pubkey和rsakv的值

sever_data = eval(result.content.decode("utf-8").replace("sinaSSOController.preloginCallBack", ''))

观察第二个请求的post表单(su,sp分别为加密后的username和password)

刚才的四个参数已经拿到,还需要对密码进行加密

ssologin.js文件中定义了加密过程,右键点击在source中打开可以看到加密算法

密码加密为RSA算法  10001为加密公钥参数另一个公钥参数为第一次GET请求的返回的pubkey

2.2加密password username

us = base64.b64encode(username)  # 加密用户名

rsaPublickey = int(pubkey, 16)
key = rsa.PublicKey(rsaPublickey, 65537) #创建公钥
message = str(servertime) + '\t' + str(nonce) + '\n' + str(password)    #拼接明文js加密文件中得到

message = message.encode('utf-8')
passwd = rsa.encrypt(message, key) #加密
passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。
print('加密后的passwd',passwd)

2.3提交post请求

login_url = 'https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)&_={}'.format(quote(username))
    data = {'entry': 'weibo',
        'gateway': '1',
        'from': 'null',
        'savestate': '30',
        'userticket': '0',
        'pagerefer': '',
        #'ssosimplelogin': '1',
        'vsnf': '1',
        #'vsnval': '',
        'su': username,
        'service': 'account',
        'servertime': servertime,
        'nonce': nonce,
        'pwencode': 'rsa2',
        'sp': passwd,
        'encoding': 'UTF-8',
        'prelt': '49',
        'rsakv' : rsakv,
        'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
        'returntype': 'META',
        #'cdult': '3',
        #'sr': '1536*864',
        #'pcid': pcid,

        }

(其中的pcid是验证码id,如登陆过程中遇到验证码, 可以利用picd下载验证码后对接打码平台破解)

拿到result 可以观察replace的url中的retcode参数 retcode=0,则说明登陆成功,如果是retcode=101则说明是失败

这就是上面三个请求中的第二个请求 根据响应头正则提取出cookies(sub, subp, login 这三个参数为主要参数,其它的没试)

拿到这个页面后会发现它重新replace到了一个新的页面(登陆页面), 同样正则提取出url后访问这个页面(带上刚才提取的cookies)

2.4登陆页面

 result2 = requests.get(urlnew1, cookies=cookies1, headers=headers)                #正在登陆界面

如果得到如下页面则登陆成功说明刚才的cookies可用,接下来就可以保存并利用此cookies登陆新浪微博了(新浪的cookies失效时间大概是15个小时左右记不清了)

同时会发现又replace到了一个新地址,我尝试抓取了这个页面分析了一下响应头发现它可能会重新set-cookies(login参数),我试的很多次中只出现了一次这种情况所以没有弄清机制,同时原cookies也可用,以防万一我还是写了一个函数更新cookies

    new_set_cookies = result2.cookies
    new_set_cookies = requests.utils.dict_from_cookiejar(new_set_cookies)           #cookies转字典
    print('new_set_cookies:', new_set_cookies)
    if new_set_cookies == {}:                                   #是否重新设置login cookie
        result2 = requests.get(urlnew2, cookies=cookies1, headers=headers)               #未知界面
        response2 = result2.headers
        print('response2未知界面:')
        html = result2.content  # 获取二进制内容
        html = html.decode('GBK', 'replace')
        print(html)
        return cookies1
    else:
        cookies1['login'] = new_set_cookies['login']
        return cookies1

详细代码上传到github后会更新链接

发布了7 篇原创文章 · 获赞 21 · 访问量 3017

猜你喜欢

转载自blog.csdn.net/qq_41389266/article/details/87355945