1、主函数(WeiboMain.py):
复制代码 代码如下:
import urllib2
import cookielib
import WeiboEncode
import WeiboSearch
if __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 re
import json
def 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 urllib
import base64
import rsa
import binascii
def 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 userNameEncoded
def 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=0
Login sucess!
果需要爬取微博中的信息,接下来只需要在Main函数后添加爬取、解析模块就可以了,比如读取某微博网页的内容:
复制代码 代码如下:
htmlContent = urllib2.urlopen(myurl).read()#得到myurl网页的所有内容(html)
大家可以根据不同的需求设计不同的爬虫模块了,模拟登陆的代码放在这里。