博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python模拟登陆新浪微博
阅读量:5340 次
发布时间:2019-06-15

本文共 6099 字,大约阅读时间需要 20 分钟。

上篇介绍了新浪微博的登陆过程,这节使用Python编写一个模拟登陆的程序。讲解与程序如下:

1、主函数(WeiboMain.py):

import urllib2import cookielibimport WeiboEncodeimport WeiboSearchif __name__ == '__main__':    weiboLogin = WeiboLogin('×××@gmail.com', '××××')#邮箱(账号)、密码    if weiboLogin.Login() == True:        print "登陆成功!"

前两个import是加载Python的网络编程模块,后面的import是加载另两个文件WeiboEncode.py和Weiboseach.py(稍后介绍)。主函数新建登陆对象,然后登陆。

2、WeiboLogin类(WeiboMain.py):

class WeiboLogin:    def __init__(self, user, pwd, enableProxy = False):        "初始化WeiboLogin,enableProxy表示是否使用代理服务器,默认关闭"        print "Initializing WeiboLogin..."        self.userName = user        self.passWord = pwd        self.enableProxy = enableProxy                self.serverUrl = "http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.11)&_=1379834957683"        self.loginUrl = "http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.11)"        self.postHeader = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Firefox/24.0'}

初始化函数,定义了两个关键的url成员:self.serverUrl用于登陆的第一步(获取servertime、nonce等),这里的第一步实质包含了的1和2;self.loginUrl用于第二步(加密用户和密码后,POST给该URL,self.postHeader是POST的头信息),这一步对应于的3。类内函数还有3个:

def Login(self):        "登陆程序"          self.EnableCookie(self.enableProxy)#cookie或代理服务器配置                serverTime, nonce, pubkey, rsakv = self.GetServerTime()#登陆的第一步        postData = WeiboEncode.PostEncode(self.userName, self.passWord, serverTime, nonce, pubkey, rsakv)#加密用户和密码        print "Post data length:\n", len(postData)        req = urllib2.Request(self.loginUrl, postData, self.postHeader)        print "Posting request..."        result = urllib2.urlopen(req)#登陆的第二步——解析新浪微博的登录过程中3        text = result.read()        try:            loginUrl = WeiboSearch.sRedirectData(text)#解析重定位结果              urllib2.urlopen(loginUrl)        except:            print 'Login error!'            return False                    print 'Login sucess!'        return True

self.EnableCookie用于设置cookie及代理服务器,网络上有很多免费的代理服务器,为防止新浪封IP,可以使用。然后使登陆的第一步,访问新浪服务器得到serverTime等信息,然后利用这些信息加密用户名和密码,构建POST请求;执行第二步,向self.loginUrl发送用户和密码,得到重定位信息后,解析得到最终跳转到的URL,打开该URL后,服务器自动将用户登陆信息写入cookie,登陆成功。

def EnableCookie(self, enableProxy):    "Enable cookie & proxy (if needed)."        cookiejar = cookielib.LWPCookieJar()#建立cookie    cookie_support = urllib2.HTTPCookieProcessor(cookiejar)    if enableProxy:        proxy_support = urllib2.ProxyHandler({
'http':'http://xxxxx.pac'})#使用代理 opener = urllib2.build_opener(proxy_support, cookie_support, urllib2.HTTPHandler) print "Proxy enabled" else: opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler) urllib2.install_opener(opener)#构建cookie对应的opener

EnableCookie函数比较简单,可以参见。

def GetServerTime(self):    "Get server time and nonce, which are used to encode the password"        print "Getting server time and nonce..."    serverData = urllib2.urlopen(self.serverUrl).read()#得到网页内容     print serverData    try:        serverTime, nonce, pubkey, rsakv = WeiboSearch.sServerData(serverData)#解析得到serverTime,nonce等         return serverTime, nonce, pubkey, rsakv    except:        print 'Get server time & nonce error!'        return None

WeiboSearch文件中的函数主要用于解析从服务器得到的数据,比较简单。

3、sServerData函数(WeiboSearch.py):

import reimport jsondef sServerData(serverData):    "Search the server time & nonce from server data"        p = re.compile('\((.*)\)')    jsonData = p.search(serverData).group(1)    data = json.loads(jsonData)    serverTime = str(data['servertime'])    nonce = data['nonce']    pubkey = data['pubkey']#    rsakv = data['rsakv']#    print "Server time is:", serverTime    print "Nonce is:", nonce    return serverTime, nonce, pubkey, rsakv

解析过程主要使用了正则表达式和JSON,这部分比较容易理解。另外Login中解析重定位结果部分函数也在这个文件中如下:

def sRedirectData(text):    p = re.compile('location\.replace\([\'"](.*?)[\'"]\)')    loginUrl = p.search(text).group(1)    print 'loginUrl:',loginUrl    return loginUrl

4、从第一步到第二步要对用户和密码进行加密,编码操作(WeiboEncode.py)

import urllibimport base64import rsaimport binasciidef PostEncode(userName, passWord, serverTime, nonce, pubkey, rsakv):    "Used to generate POST data"            encodedUserName = GetUserName(userName)#用户名使用base64加密     encodedPassWord = get_pwd(passWord, serverTime, nonce, pubkey)#目前密码采用rsa加密     postPara = {        'entry': 'weibo',        'gateway': '1',        'from': '',        'savestate': '7',        'userticket': '1',        'ssosimplelogin': '1',        'vsnf': '1',        'vsnval': '',        'su': encodedUserName,        'service': 'miniblog',        'servertime': serverTime,        'nonce': nonce,        'pwencode': 'rsa2',        'sp': encodedPassWord,        'encoding': 'UTF-8',        'prelt': '115',        'rsakv': rsakv,             'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',        'returntype': 'META'    }    postData = urllib.urlencode(postPara)#网络编码    return postData

PostEncode函数构建POST的消息体,要求构建得到内容与真正登陆所需的信息相同。难点在用户名和密码的加密方式:

def GetUserName(userName):    "Used to encode user name"        userNameTemp = urllib.quote(userName)    userNameEncoded = base64.encodestring(userNameTemp)[:-1]    return userNameEncodeddef get_pwd(password, servertime, nonce, pubkey):    rsaPublickey = int(pubkey, 16)    key = rsa.PublicKey(rsaPublickey, 65537) #创建公钥    message = str(servertime) + '\t' + str(nonce) + '\n' + str(password) #拼接明文js加密文件中得到    passwd = rsa.encrypt(message, key) #加密    passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。    return passwd

新浪登录过程,密码的加密方式原来是SHA1,现在变为了RSA,以后可能还会变化,但是各种加密算法在Python中都有对应的实现,只要发现它的加密方式(破碎的心),程序比较易于实现。

到这里,Python模拟登陆新浪微博就成功了,运行输出:

loginUrl: http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&ssosavestate=1390390056&ticket=ST-MzQ4NzQ5NTYyMA==-1387798056-xd-284624BFC19FE242BBAE2C39FB3A8CA8&retcode=0Login sucess!

如果需要爬取微博中的信息,接下来只需要在Main函数后添加爬取、解析模块就可以了,比如读取某微博网页的内容:

htmlContent = urllib2.urlopen(myurl).read()#得到myurl网页的所有内容(html)

大家可以根据不同的需求设计不同的爬虫模块了,模拟登陆的代码放在。

转载于:https://www.cnblogs.com/houkai/p/3488468.html

你可能感兴趣的文章
linux下编译复数类型引发的错误:expected unqualified-id before '(' token
查看>>
codeforces 1041A Heist
查看>>
字典常用方法
查看>>
Spring Cloud Stream消费失败后的处理策略(三):使用DLQ队列(RabbitMQ)
查看>>
bzoj1048 [HAOI2007]分割矩阵
查看>>
Java中的编码
查看>>
PKUWC2018 5/6
查看>>
As-If-Serial 理解
查看>>
洛谷P1005 矩阵取数游戏
查看>>
在Silverlight中使用HierarchicalDataTemplate为TreeView实现递归树状结构
查看>>
无线通信基础(一):无线网络演进
查看>>
如何在工作中快速成长?阿里资深架构师给工程师的10个简单技巧
查看>>
WebSocket 时时双向数据,前后端(聊天室)
查看>>
关于python中带下划线的变量和函数 的意义
查看>>
linux清空日志文件内容 (转)
查看>>
安卓第十三天笔记-服务(Service)
查看>>
Servlet接收JSP参数乱码问题解决办法
查看>>
【bzoj5016】[Snoi2017]一个简单的询问 莫队算法
查看>>
Ajax : load()
查看>>
MySQL-EXPLAIN执行计划Extra解释
查看>>