PC登录新浪微博时,在客户端用js预先对用户名、密码都进行了加密,而且在POST之前会GET一组参数,这也将作为POST_DATA的一部分。这样,就不能用通常的那种简单方法来模拟POST登录(比如人人网)。
由于要用的一部分微博数据用API获取不方便,所以还是要自己写个小爬虫,模拟登录是必不可少的。琢磨了一下这个东西,最终登录成功。
1,在提交POST请求之前,需要GET获取两个参数。
地址是:/sso/login.php?client=ssologin.js(v1.3.18)
得到的数据中有"servertime"和"nonce"的值,是随机的,其他值貌似没什么用。
2,通过httpfox观察POST的数据,参数较复杂,其中“su"是加密后的username,"sp"是加密后的password。"servertime"和”nonce"是上一步得到的。其他参数是不变的。
username经过了BASE64计算:username=base64.encodestring(urllib.quote(username))[:-1];
password经过了三次SHA1加密,且其中加入了servertime和nonce的值来干扰。
即:两次SHA1加密后,将结果加上servertime和nonce的值,再SHA1算一次。
将参数组织好,POST请求。这之后还没有登录成功。
POST后得到的内容中包含一句location.replace("/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&retcode=101&reason=%B5%C7%C2%BC%C3%FB%BB%F2%C3%DC%C2%EB%B4%ED%CE%F3");
这是登录失败时的结果,登录成功后结果与之类似,不过retcode的值是0。接下来再请求这个URL,这样就成功登录到微博了。
记得要提前build缓存。
下面是完整代码(没加注释,凑合看吧):
#!/usr/bin/envpython
#coding=utf8
importurllib
importurllib2
importcookielib
importbase64
importre
importjson
importhashlib
cj=cookielib.LWPCookieJar()
cookie_support=urllib2.HTTPCookieProcessor(cj)
opener=urllib2.build_opener(cookie_support,urllib2.HTTPHandler)
urllib2.install_opener(opener)
postdata={
'entry':'weibo',
'gateway':'1',
'from':'',
'savestate':'7',
'userticket':'1',
'ssosimplelogin':'1',
'vsnf':'1',
'vsnval':'',
'su':'',
'service':'miniblog',
'servertime':'',
'nonce':'',
'pwencode':'wsse',
'sp':'',
'encoding':'UTF-8',
'url':'
'returntype':'META'
}
defget_servertime():
url='/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=dW5kZWZpbmVk&client=ssologin.js(v1.3.18)&_=1329806375939'
data=urllib2.urlopen(url).read()
p=pile('\((.*)\)')
try:
json_data=p.search(data).group(1)
data=json.loads(json_data)
servertime=str(data['servertime'])
nonce=data['nonce']
returnservertime,nonce
except:
print'Getsevertimeerror!'
returnNone
defget_pwd(pwd,servertime,nonce):
pwd1=hashlib.sha1(pwd).hexdigest()
pwd2=hashlib.sha1(pwd1).hexdigest()
pwd3_=pwd2+servertime+nonce
pwd3=hashlib.sha1(pwd3_).hexdigest()
returnpwd3
defget_user(username):
username_=urllib.quote(username)
username=base64.encodestring(username_)[:-1]
returnusername
deflogin():
username='你的登录邮箱'
pwd='你的密码'
url='/sso/login.php?client=ssologin.js(v1.3.18)'
try:
servertime,nonce=get_servertime()
except:
return
globalpostdata
postdata['servertime']=servertime
postdata['nonce']=nonce
postdata['su']=get_user(username)
postdata['sp']=get_pwd(pwd,servertime,nonce)
postdata=urllib.urlencode(postdata)
headers={'User-Agent':'Mozilla/5.0(X11;Linuxi686;rv:8.0)Gecko/0101Firefox/8.0'}
req=urllib2.Request(
url=url,
data=postdata,
headers=headers
)
result=urllib2.urlopen(req)
text=result.read()
p=pile('location\.replace\(\'(.*?)\'\)')
try:
login_url=p.search(text).group(1)
#printlogin_url
urllib2.urlopen(login_url)
print"登录成功!"
except:
print'Loginerror!'
login()
转载:/note/67245/