模拟登录新浪微博-python
来源:互联网 发布:js强制弹窗 编辑:程序博客网 时间:2024/04/29 12:32
模拟登录新浪微博(python)
reference:
http://www.jb51.net/article/46053.htm
http://blog.csdn.net/u010487568/article/details/46932839
新浪微博的登录流程不是简单的post用户名密码,经过查询资料与抓包分析,它首先会用ssologin.js文件对用户名、密码以及服务器、客户端的信息先进行处理,再发送给服务器进行身份认证。目前,新浪的客户端版本已升级到1.4.18,经过测试,可以完成登录微博,并获取用户主页。本文主要对整个流程进行分析,并给予主要代码。
1.抓包分析登录流程
首先关注到登录的时候有两个包
第一个是prelogin.php,第二个login.php。
可以知道login.php中应该是发往服务器的身份认证信息,先看一下它的post数据,
这里可以看到有一些固定的数据,但是也有一些我们不知道的数据,重点关注servertime,nonce,rsakv,sp 只从现有信息无法获得这几个数据,现在看一下prelogin.php的返回数据
这里看到了我们关注的数据,所以我们只要先请求一下prelogin就可以了。现在看一下怎样请求
prelogin
用get的方式,这里后面跟的参数中有一个su,还有_后面那个是客户端的时间(毫秒形式),这些是我们不知道的,在找资料中可以在 (http://login.sina.com.cn/)中查看源码,这里面有一个js文件,如图
进入后可以看到http://login.sina.com.cn/js/sso/ssologin.js 的代码内容,下载下来后,搜索关键代码
——–su———-
可以看到是用base64处理过的,这里是我的python实现
su = base64.b64encode(urllib.quote(self.username))
——–sp———-
python实现
def get_pwd(self,pwd, servertime, nonce, pubkey): rsaPublickey = int(pubkey, 16) key = rsa.PublicKey(rsaPublickey, 65537) #创建公钥 message = str(servertime) + '\t' + str(nonce) + '\n' +str(pwd)#拼接明文js加密文件中得到 passwd = rsa.encrypt(message, key) #加密 passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制 return passwd
——–plt———-
客户端计时,python实现
def __mtime(self): '''Return the current time by milli-second''' return long('%.0f' % (time.time() * 1000))
之后我们就可以开始请求prelogin了
login
在login流程中,最重要的是构造post数据,完全按照抓包数据来处理。
这里有一个参数是prelt,在js文件中搜索,可以看到为现在时间减去了服务器返回的exectime这个时间值
python实现
endPre = self.mtime() print 'endPre:%d' % endPre prelt = endPre - plt - long(data['exectime'])
对于包头,有的资料显示要构造得很详细,比如Content-Type、Cookies、Content-Length,但是我测试后发现只要用User-Agent就可以了。
有的资料到请求login后只要判断返回的js代码中是否有location.replace就可以了,但是为了之后要继续做爬虫等,还是需要获得uid的信息,所以继续抓包研究。
ajaxlogin
看到它的返回内容中有uid 以及 userdomain
homepage
请求homepage,它的url为’http://weibo.com/u/’ + uid +’/home’ + userdomain
得到返回的内容为用户的首页,可以通过状态码来判断是否获取成功
2.主要代码分析
(1)cookie设置
def set_cookie(): ''' 设置cookies ''' cookiejar = cookielib.LWPCookieJar() cookie_support = urllib2.HTTPCookieProcessor(cookiejar) opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler) urllib2.install_opener(opener)
先使用cookielib与urllib2配合,处理cookie相关事宜,先配置好后,便于之后爬虫爬取网页
(2)预登录 prelogin
def prelogin(self): ''' 预登录 获得变量字典 :return: args_dict ''' #获得用户名base63后的结果su su = base64.b64encode(urllib.quote(self.username)) #获得客户端时间plt plt = self.__mtime() parameters = { 'entry': 'weibo', 'callback': 'sinaSSOController.preloginCallBack', 'su': su, 'rsakt': 'mod', 'checkpin': '1', 'client': 'ssologin.js(v1.4.5)', '_': plt } url = 'http://login.sina.com.cn/sso/prelogin.php?' + urllib.urlencode(parameters) data = urllib2.urlopen(url).read() #获得返回内容中的变量字典 p = re.compile('\((.*)\)') try: json_data = p.search(data).group(1) args_dict = json.loads(json_data) args_dict['su'] = su return args_dict except: print 'prelogin error!' return None
预登录前,先得到su和plt,然后发送get请求的,得到返回的变量字典
(3)login 登录
首先请求login.php
postdata = { 'entry': 'weibo', 'gateway': '1', 'from': '', 'savestate': '7', 'useticket': '1', 'pagerefer': '', 'vsnf': '1', 'su': args_dict['su'], 'service': 'miniblog', 'servertime': args_dict['servertime'], 'nonce': args_dict['nonce'], 'pwencode': 'rsa2', 'rsakv': args_dict['rsakv'], 'sp': sp, 'encoding': 'UTF-8', 'prelt': '27', 'url': 'http://www.weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack', 'returntype': 'META' } postdata = urllib.urlencode(postdata) headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:8.0) Gecko/20100101 Firefox/8.0'} req = urllib2.Request( url=url, data=postdata, headers=headers )
这里有一个疑问,最开始,我总是请求失败,我的postdata 里的url是这样写的
‘url’ :
‘http%3A%2F%2Fweibo.com%2Fajaxlogin.php%3Fframelogin%3D1%26callback%3Dparent.sinaSSOController.feedBackUrlCallBack’
按理说转义字符应该没有影响不知道为什么去掉这句就可以了。。。(可以再思考一下)
然后,我请求了ajaxlogin获得uid
def get_uinfo(self): ''' 获得uid,userdomain :return: uid,userdomain ''' ajaxlogin_url = 'http://weibo.com//ajaxlogin.php?framelogin=1&callback=' \ 'parent.sinaSSOController.feedBackUrlCallBack&sudaref=weibo.com' try: res = urllib2.urlopen(ajaxlogin_url).read() # print res.decode('gb2312').encode('utf-8') patt = re.compile('\((.*?)\)') user_info = patt.search(res).group(1) user_info = json.loads(user_info) uid = user_info['userinfo']['uniqueid'] userdomain = user_info['userinfo']['userdomain'] return uid, userdomain except: print 'get user info error'
最后,我请求homepage
homepage_url = 'http://weibo.com/u/' + uid +'/home' + userdomaintry: result = urllib2.urlopen(homepage_url) if result.code == 200: print 'login successful'except: print 'login error'
然后就成功啦!
- 模拟登录新浪微博(Python)
- Python模拟新浪微博登录
- python 模拟登录新浪微博
- python模拟登录新浪微博
- 模拟登录新浪微博(Python)
- python模拟登录新浪微博
- python模拟登录新浪微博
- python模拟登录新浪微博
- 模拟登录新浪微博-python
- Python 模拟登录新浪微博
- 模拟登录新浪微博
- 爬取新浪微博数据+新浪微博模拟登录+mysql+python
- python模拟登录新浪微博自动获得调用新浪api所需的code
- python模拟登录新浪微博自动获得调用新浪api所需的code
- python登录新浪微博
- httpClient4模拟登录新浪微博
- scrapy模拟登录新浪微博
- node.js 模拟登录新浪微博
- isspace
- XCode中遇到not available in automatic reference counting mode 报错
- 泛型:有限通配符的用法
- [NSIS]NSIS——Qt程序发布工具
- leetcode330:Patching Array(贪心)
- 模拟登录新浪微博-python
- 多线程笔记
- 对model的解归档
- JAVA中的TCP通信(多线程)
- atoi的用法
- 【LeetCode】160. Intersection of Two Linked Lists
- GC垃圾回收机制与内存泄漏
- Linux waitpid
- c#webservice的简单示例