Python模拟登陆新浪微博


本文转自:http://blog.csdn.net/andrewseu/article/details/48730735
前几天想在学校论坛上淘一个二手蓝牙鼠标,没有时间盯着论坛就写了Python程序模拟登陆,每隔一段时间检测,一旦有目标物品出现,发短信通知(重要的通知还是用短信哈)
学校论坛模拟登陆很简单,用fiddler分析一cookies即可。今天在首页看到这篇博文,感觉挺有意思,转一个。

1.前言

从模拟登录这件事上,可以看出公司之间的技术水平,对安全的重视程度。之前做过豆瓣的模拟登录(链接),直接做一个post请求就OK,简直easy. 但是到新浪微博上,这个方法完全行不通,新浪微博简直了!!!各种加密,各种跳转,登录过程神烦!!!在参考了很多的博文,历经无数次失败之后,终于,我也成功登录上了!(●'◡'●)


2.登录过程分析

我一直用的是chrome浏览器,所以在开始做模拟登录的时候也是用chrome看登录过程,但是!并没有获得很多有用的信息,之后看网上很多推荐fiddler抓包,但是看着太乱了,也并没有真正去分析这个软件. 之后我转向了火狐,奇迹发现了,我看到了登录的全过程,网页的响应也很容易查看(chrome响应看不到的情况下也可以).因此,复杂的登录分析还是用火狐吧!

好,接下来就是见证奇迹的时刻,来看看登录到底经历了哪些过程:

首先,在输入用户名后,会进行预登录,网址为:http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=ZW5nbGFuZHNldSU0MDE2My5jb20%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_=1443156845536,通过响应(sinaSSOController.preloginCallBack({"retcode":0,"servertime":1443156842,"pcid":"gz-e88b75a929252baec7c12c741985eaa45627","nonce":"2L4IZ3","pubkey":"EB2A38568661887FA180BDDB5CABD5F21C7BFD59C090CB2D245A87AC253062882729293E5506350508E7F9AA3BB77F4333231490F915F6D63C55FE2F08A49B353F444AD3993CACC02DB784ABBB8E42A9B1BBFFFB38BE18D78E87A0E41B9B8F73A928EE0CCEE1F6739884B9777E4FE9E88A1BBE495927AC4A799B3181D6442443","rsakv":"1330428213","showpin":0,"exectime":16})),我们可以获得四个有用的变量,servertime、nonce、pubkey和rsakv.

新浪微博的用户名加密目前采用Base64加密算法,而新浪微博登录密码的加密算法使用RSA2,这是模拟登陆的重点,需要先创建一个rsa公钥,公钥的两个参数新浪微博都给了固定值,第一个参数是登录第一步中的pubkey,第二个参数是js加密文件中的‘10001’. 这两个值需要先从16进制转换成10进制,把10001转成十进制为65537,随后加入servertime和nonce再次加密.

在做完准备工作之后,可以看看登录需要什么数据,切换到post请求,网址为:http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18),查看提交的表单数据,如下图:

主要的需要提交数据:

su:base64加密过后的用户名

servertime/nonce/rsakv之前预登陆获取到了

sp是加密过户的密码


表单数据获取到了之后自然就是提交表单数据,你以为这样就好了吗?太naive了!

提交之后返回的并不是微博个人主页,而是一段重定向的代码,大概是这样:

注意红线部分,如果是retcode=0则表示成功,否则前面的过程就有问题哦==

通过正则表达式获取到重定向的网址,提交请求之后就大功告成啦!



3.技术要点

3.1 几个库

cookielib:The cookie module defines classes for abstracting the concept ofcookies, an HTTP state management mechanism. It supports both simple string-onlycookies, and provides an abstraction for having any serializable data-type ascookie value. 用来保存cookies.

urllib2:The urllib2 module defines functions and classes which help in openingURLs (mostly HTTP) in a complex world — basic and digest authentication,redirections, cookies and more. 用来发送请求获取网页数据,与cookielib配合可以利用cookie访问.

json:Json is a lightweight data interchange format inspired by javascript object literal syntax(although it is not a strict subset of JavaScript ).

3.2 正则表达式

正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大.

具体可以参考:Python正则表达式指南 


4.源代码

[python]  view plain copy
  1. # -*- coding: utf-8 -*-  
  2. ########################  
  3. #author:Andrewseu  
  4. #date:2015/9/23  
  5. #login weibo  
  6. ########################  
  7.   
  8. import sys  
  9. import urllib  
  10. import urllib2  
  11. import cookielib  
  12. import base64  
  13. import re  
  14. import json  
  15. import rsa  
  16. import binascii  
  17. #import requests  
  18. #from bs4 import BeautifulSoup  
  19.   
  20. #新浪微博的模拟登陆  
  21. class weiboLogin:  
  22.     def enableCookies(self):  
  23.             #获取一个保存cookies的对象  
  24.             cj = cookielib.CookieJar()  
  25.             #将一个保存cookies对象和一个HTTP的cookie的处理器绑定  
  26.             cookie_support = urllib2.HTTPCookieProcessor(cj)  
  27.             #创建一个opener,设置一个handler用于处理http的url打开  
  28.             opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)  
  29.             #安装opener,此后调用urlopen()时会使用安装过的opener对象  
  30.             urllib2.install_opener(opener)  
  31.   
  32.     #预登陆获得 servertime, nonce, pubkey, rsakv  
  33.     def getServerData(self):  
  34.             url = 'http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=ZW5nbGFuZHNldSU0MDE2My5jb20%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_=1442991685270'  
  35.             data = urllib2.urlopen(url).read()  
  36.             p = re.compile(' (.) ')  
  37.             try:  
  38.                     json_data = p.search(data).group(1)  
  39.                     data = json.loads(json_data)  
  40.                     servertime = str(data['servertime'])  
  41.                     nonce = data['nonce']  
  42.                     pubkey = data['pubkey']  
  43.                     rsakv = data['rsakv']  
  44.                     return servertime, nonce, pubkey, rsakv  
  45.             except:  
  46.                     print 'Get severtime error!'  
  47.                     return None  
  48.                   
  49.   
  50.     #获取加密的密码  
  51.     def getPassword(self, password, servertime, nonce, pubkey):  
  52.             rsaPublickey = int(pubkey, 16)  
  53.             key = rsa.PublicKey(rsaPublickey, 65537#创建公钥  
  54.             message = str(servertime) + '\t' + str(nonce) + '\n' + str(password) #拼接明文js加密文件中得到  
  55.             passwd = rsa.encrypt(message, key) #加密  
  56.             passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。  
  57.             return passwd  
  58.   
  59.     #获取加密的用户名  
  60.     def getUsername(self, username):  
  61.             username_ = urllib.quote(username)  
  62.             username = base64.encodestring(username_)[:-1]  
  63.             return username  
  64.   
  65.      #获取需要提交的表单数据     
  66.     def getFormData(self,userName,password,servertime,nonce,pubkey,rsakv):  
  67.         userName = self.getUsername(userName)  
  68.         psw = self.getPassword(password,servertime,nonce,pubkey)  
  69.           
  70.         form_data = {  
  71.             'entry':'weibo',  
  72.             'gateway':'1',  
  73.             'from':'',  
  74.             'savestate':'7',  
  75.             'useticket':'1',  
  76.             'pagerefer':'http://weibo.com/p/1005052679342531/home?from=page_100505&mod=TAB&pids=plc_main',  
  77.             'vsnf':'1',  
  78.             'su':userName,  
  79.             'service':'miniblog',  
  80.             'servertime':servertime,  
  81.             'nonce':nonce,  
  82.             'pwencode':'rsa2',  
  83.             'rsakv':rsakv,  
  84.             'sp':psw,  
  85.             'sr':'1366*768',  
  86.             'encoding':'UTF-8',  
  87.             'prelt':'115',  
  88.             'url':'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',  
  89.             'returntype':'META'  
  90.             }  
  91.         formData = urllib.urlencode(form_data)  
  92.         return formData  
  93.   
  94.     #登陆函数  
  95.     def login(self,username,psw):  
  96.             self.enableCookies()  
  97.             url = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)'  
  98.             servertime,nonce,pubkey,rsakv = self.getServerData()  
  99.             formData = self.getFormData(username,psw,servertime,nonce,pubkey,rsakv)  
  100.             headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0'}  
  101.             req  = urllib2.Request(  
  102.                     url = url,  
  103.                     data = formData,  
  104.                     headers = headers  
  105.             )  
  106.             result = urllib2.urlopen(req)  
  107.             text = result.read()  
  108.             print text  
  109.             #还没完!!!这边有一个重定位网址,包含在脚本中,获取到之后才能真正地登陆  
  110.             p = re.compile('location\.replace [\'"](.?)[\'"] ')  
  111.             try:  
  112.                     login_url = p.search(text).group(1)  
  113.                     print login_url  
  114.                     #由于之前的绑定,cookies信息会直接写入  
  115.                     urllib2.urlopen(login_url)  
  116.                     print "Login success!"  
  117.             except:  
  118.                     print 'Login error!'  
  119.                     return 0  
  120.   
  121.             #访问主页,把主页写入到文件中  
  122.             url = 'http://weibo.com/u/2679342531/home?topnav=1&wvr=6'  
  123.             request = urllib2.Request(url)  
  124.             response = urllib2.urlopen(request)  
  125.             text = response.read()  
  126.             fp_raw = open("e://weibo.html","w+")  
  127.             fp_raw.write(text)  
  128.             fp_raw.close()  
  129.             #print text  
  130.               
  131. wblogin = weiboLogin()  
  132. print '新浪微博模拟登陆:'  
  133. username = raw_input(u'用户名:')  
  134. password = raw_input(u'密码:')  
  135. wblogin.login(username,password)  

5.结果截图

根据提示输入用户名和密码:

主页文件:


and then? 随心所欲的做自己喜欢的事~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值