模拟登录新浪微博(Python)
http://www.douban.com/note/201767245/?start=100&post=ok#last
模拟登录开源代码
https://github.com/Ncerzzk/weibo
微博加密方法
http://hi.baidu.com/enmzqbeadvfhiye/item/4018b4e7775cd3edfa42bad3
http://www.cnblogs.com/mouse-coder/archive/2013/03/03/2941265.html
Update: 如果只是写个小爬虫,访问需要登录的页面,采用填入cookie 的方法吧,简单粗暴有效,详细见:
http://www.douban.com/note/264976536/
模拟登陆有时需要了解js 加密(散列)方法,输入验证法等,同一段代码很难一直有效。
正文:
PC 登录新浪微博时, 在客户端用js预先对用户名、密码都进行了加密, 而且在POST之前会GET 一组参数,这也将作为POST_DATA 的一部分。 这样, 就不能用通常的那种简单方法来模拟POST 登录( 比如 人人网 )。
由于要用的一部分微博数据用API获取不方便, 所以还是要自己写个小爬虫, 模拟登录是必不可少的。琢磨了一下这个东西,最终登录成功。
1, 在提交POST请求之前, 需要GET 获取两个参数。
地址是: http://login.sina.com.cn/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(" http://weibo.com/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/env python
#coding=utf8
import urllib
import urllib2
import cookielib
import base64
import re
import json
import hashlib
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': ' http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
'returntype': 'META'
}
def get_servertime():
url = ' http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=dW5kZWZpbmVk&client=ssologin.js(v1.3.18)&_=1329806375939'
data = urllib2.urlopen(url).read()
p = re.compile('\((.*)\)')
try:
json_data = p.search(data).group(1)
data = json.loads(json_data)
servertime = str(data['servertime'])
nonce = data['nonce']
return servertime, nonce
except:
print 'Get severtime error!'
return None
def get_pwd(pwd, servertime, nonce):
pwd1 = hashlib.sha1(pwd).hexdigest()
pwd2 = hashlib.sha1(pwd1).hexdigest()
pwd3_ = pwd2 + servertime + nonce
pwd3 = hashlib.sha1(pwd3_).hexdigest()
return pwd3
def get_user(username):
username_ = urllib.quote(username)
username = base64.encodestring(username_)[:-1]
return username
def login():
username = '你的登录邮箱'
pwd = '你的密码'
url = ' http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.18)'
try:
servertime, nonce = get_servertime()
except:
return
global postdata
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; Linux i686; rv:8.0) Gecko/20100101 Firefox/8.0'}
req = urllib2.Request(
url = url,
data = postdata,
headers = headers
)
result = urllib2.urlopen(req)
text = result.read()
p = re.compile('location\.replace\(\'(.*?)\'\)')
try:
login_url = p.search(text).group(1)
#print login_url
urllib2.urlopen(login_url)
print "登录成功!"
except:
print 'Login error!'
login()
欢迎交流。
模拟登陆有时需要了解js 加密(散列)方法,输入验证法等,同一段代码很难一直有效。
正文:
PC 登录新浪微博时, 在客户端用js预先对用户名、密码都进行了加密, 而且在POST之前会GET 一组参数,这也将作为POST_DATA 的一部分。 这样, 就不能用通常的那种简单方法来模拟POST 登录( 比如 人人网 )。
由于要用的一部分微博数据用API获取不方便, 所以还是要自己写个小爬虫, 模拟登录是必不可少的。琢磨了一下这个东西,最终登录成功。
1, 在提交POST请求之前, 需要GET 获取两个参数。
地址是: http://login.sina.com.cn/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(" http://weibo.com/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/env python
#coding=utf8
import urllib
import urllib2
import cookielib
import base64
import re
import json
import hashlib
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': ' http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
'returntype': 'META'
}
def get_servertime():
url = ' http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=dW5kZWZpbmVk&client=ssologin.js(v1.3.18)&_=1329806375939'
data = urllib2.urlopen(url).read()
p = re.compile('\((.*)\)')
try:
json_data = p.search(data).group(1)
data = json.loads(json_data)
servertime = str(data['servertime'])
nonce = data['nonce']
return servertime, nonce
except:
print 'Get severtime error!'
return None
def get_pwd(pwd, servertime, nonce):
pwd1 = hashlib.sha1(pwd).hexdigest()
pwd2 = hashlib.sha1(pwd1).hexdigest()
pwd3_ = pwd2 + servertime + nonce
pwd3 = hashlib.sha1(pwd3_).hexdigest()
return pwd3
def get_user(username):
username_ = urllib.quote(username)
username = base64.encodestring(username_)[:-1]
return username
def login():
username = '你的登录邮箱'
pwd = '你的密码'
url = ' http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.3.18)'
try:
servertime, nonce = get_servertime()
except:
return
global postdata
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; Linux i686; rv:8.0) Gecko/20100101 Firefox/8.0'}
req = urllib2.Request(
url = url,
data = postdata,
headers = headers
)
result = urllib2.urlopen(req)
text = result.read()
p = re.compile('location\.replace\(\'(.*?)\'\)')
try:
login_url = p.search(text).group(1)
#print login_url
urllib2.urlopen(login_url)
print "登录成功!"
except:
print 'Login error!'
login()
欢迎交流。
同问,这一段代码还能模拟登陆吗?需要做哪些改进呀?
能给我发一份您的代码吗?新手学习了,谢谢,350478489@qq.com
不好意思,豆瓣不经常上,https://github.com/N cerzzk/weibo
顶~写的真好
thank you~
不错,正在试用!
抓包后搜到这文,不错!!
我很好奇, 你是怎么知道
" username 经过了BASE64 计算",
"password 经过了三次SHA1 加密, 且其中加入了 servertime 和 nonce 的值来干扰"的。
莫非是新浪内部人员?
搜索引擎这么发达,方法总是有的
识别验证码
请问显示了“登陆成功”,可是用urllib2.Request('某用户主页'),显示的内容,仍然是请登录,什么情况
模拟登陆之后,尝试在request个人的主页,不过得到的response跟页面显示的东西不一样。这是为什么呢?是因为之后还有其余的操作要做么,比如动态加载之类的操作。不太明白。。。
模拟登陆成功,并返回cookie头信息,下次在request个人的主页时要将其用来配置头信息就可以正常获取了。
这个方法的确OK。
或者将urllib2 install 包含cookie_handler的opener之后, 直接就可以访问了。
现在加密好像变了。 不能登陆!
weibo 加密的那个 js 文件是哪个?
楼主,post请求中的参数很多在form表单中找不到,请问一下这些参数是哪来的呢?
找个浏览器插件查一下就OK
现在貌似不能用了??
可能是新浪网页有变化,比如散列方法等
用chrome的”inspect element“,可以看到加密的逻辑,呵呵
n/t35/miniblog/stati c/js/sso.js?version= 23acb1a643a3d133"></script>
(爬虫新手,多多指教 ^_^)
<script type="text/javascript" src="http://js.t.sinajs.c
password = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(password)) + me.servertime + me.nonce); // 空字符串为了避免各项全部是数字时造成数字相加而不是字符串链接的情况
nice
ttp://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=dW5kZWZpbmVk&client=ssologin.js(v1.3.18)&_=1329806375939'
这个是哪里获取的?
看了你的代码,我用java写了一个,过程基本一致,老是提示用户名密码不对,能帮忙看下吗?
java 很久不用了...
最近是不是不能用了?登录改版了吗?
用不了了吗?
各位豆友,关于程序现在是否还管用的问题,我实在是不能回答:当时需要模拟登录的功能,所以写了这个模块并将其分享,附上源码是为了大家看起来更方便、清楚。互联网站为了安全而更改登录协议(比如加密算法)是很正常且必要的行为,所以模拟登录不可能一劳永逸。所以如果现在需要这个模拟登录的功能,需要自己模仿上述方法来尝试就OK了;在下目前不需要该功能,不会对其维护。谢谢各位的支持~
用requests库实现:https://gist.github. com/3621775
@Zhao Xiaohong 这么强大?
requests 的确是个好东西
不错不错!必须多多学习!
果然强大!
有个问题想请教下楼主,我想下载某个作者的全部微博,但是微博在一页中是分段加载的,一页中有50条微博,但是只能下载15条左右。我尝试分析它加载时传递的参数,但是没能搞明白,不知道楼主尝试过没有
既然只是想下载微博, 那么为何不用新浪API呢, 总归是比自己的网页爬虫快的。 hostrong/weibosdk
可以参考这个,写起来很简单: https://github.com/g
在提交POST请求之前, 需要GET 获取两个参数。 m.cn/sso/login.php?c lient=ssologin.js(v1 .3.18)
地址是:http://login.sina.co
得到的数据中有 "servertime" 和 "nonce" 的值, 是随机的,其他值貌似没什么用。
博主,其他看懂的。这一步没看懂,是怎么获取的啊,我用httpfox和fiddler找get的包,都没找到啊,谢谢指教啊,post的包里su和sp我倒是看到了。
新浪改版了;自己试试查看下别的地址吧。
现在已经是 ssologin.js1.4.4 了,不过改改就能用。
您好,有问题请教,给您留了豆邮,能否查看下?
SHA1 只是做摘要,好像不能称为加密吧?就是英文digest,这些技术统统在http权威指南有介绍。
再一个之所以有servertime 和 nonce,这些是server考虑到抗重放攻击和实际应用做的考虑。而这些都在HTTP权威指南有介绍。
很不解的是,为什么对passwd做三次sha1摘要,一次就足够啦。
你看他的代码,不是对pwd做三次加密,而是每次都加其他salt组后后再加密。
增加破解难度
的确算加密。但总归是为了密码安全性
博主你好,我也想问你那个最终post参数里边的url的地址是怎么知道的呢?我现在需要在其他网站模拟,但不知道这个url从哪里知道?
现在新浪默认的登录时rsa2,我说怎么密码有256位呢 把登录方式改一下登录成功
博主你好,你上面说要retcode为0才是登录成功。我遇到retcode为404是什么原因呢?一样的代码在本地是模拟成功的不过在SAE上面就404了。。
把这一行更改一下就可以了
p = re.compile('location\.replace\(\'(.*?)\'\)')
更改成:
p = re.compile('location\.replace\(\"(.*?)\"\)')
我刚试了一下。还可以登录成功。
现在不能登陆了呢,貌似新浪登陆方式又改了
您好,请问您的这个“把登录方式改一下”是什么意思? 256的sp怎么算出来呢?
貌似这一两天开始不能用wsse加密方式了,只能用rsa2了
具体能说下么
加密方式变了?
请问你是如何知道使用的加密方式的????
目前新浪微博使用老方法登录不上去 很急阿。。。
求教 你是怎么知道登录时使用的加密方法,还有现在的登录方法,使用rsa怎么做的阿 菜鸟不会 。。。。
折腾2天终于出来了 原来这么简单。。。
你找到新的方法了?求解答呀,求共享。
使用google + 猜测
求分享……vipgss@gmail.com
求共享,QQ:382958619,求指导~~~
求指导,求共享,QQ:382958619
跪求指导啊,您都改了些什么?邮箱:jenny_bm@163.com
mark
纠结于频繁变换的加密机制的豆友,可以用这个naive的方法来模拟登录: m/note/264976536/
http://www.douban.co
加密机制我没有时间时刻去关注,也许你可以采用这个方法:http://www.douban.co m/note/264976536/
http://hi.baidu.com/ enmzqbeadvfhiye/item /4018b4e7775cd3edfa4 2bad3
以前留的url不见了。。。。。
http://www.douban.com/link2?url=http%3A//hi.baidu.com/enmzqbeadvfhiye/item/4018b4e7775cd3edfa42bad3
请问您的RSA是通过easy_install安装的还是exe文件拷贝过去,您用的python是哪个版本的,下的RSA又是针对哪个版本的?我用的2.6,easy_install安装完不能用,无论是import rsa还是from site-packages import rsa都提示unresolved import。小白一个,问题幼稚请多见谅包含~
https://pypi.python. org/pypi/rsa/3.1.1 下载rsa-3.1.1.tar.gz (md5) 解压后 我的是linux 命令sudo python setup。py install
使用RSA登录weibo的文章,python + RSA2 + Cookies, http://yoyzhou.githu b.com/blog/2013/03/1 8/sina-weibo-login-s imulator-in-python/
文章基于上面的讨论(感谢),并且使用python实现。
请问新浪微博登陆后 那些数据怎么爬 感觉源代码里没有那些想要的东西啊 要用到什么 三克油
犀利,根据这篇文章的指示http://www.cnblogs.c om/mouse-coder/archi ve/2013/03/03/294126 5.html,目前登录还是成功的
我想请问一下你解决问题,可以获取全部的微博了吗?因为我之前用新浪微博的API受限制,但是还是需要能够获取全部的微博,不知道你有没有什么解决办法。
已经登录了,但是抓某些页面,内容是返回到http://weibo.com/sor ry?sysbusy
这里还有什么陷阱?
模拟登录老提示验证码错误,不知道哪里出了错
必须顶一个,想模拟登录几个需要签到的网站,参考了~
入门级菜鸟表示应该怎样知道login需要请求的url,,我查看元素了很久还是没找到>_<
network里 ,点击下面的红色● ,开始抓包 。然后你看到 post 200 的字样 ,点击 就可以看到了 response , headers 什么的 。
喔喔谢谢一会去试试
login 的都是POST请求,看一下那些POST 请求带有类似用户名/邮箱、密码的参数,对应的URL一般就是LOGIN需要的URL
登陆成功了~获取页面和每个微博也都搞定了,现在点赞/删除微博的时候,照post发过去,请求返回的都是系统繁忙,好奇怪
mark
请教楼主,验证码问题怎么攻克呢?用cookie或者代理服务器有什么弊端?小白问题请见谅!
能把你修改好的代码发一下吗? 我邮箱 xuxiuning@163.com 谢谢~~~
同求,谢谢
急求帮助呀,Post得到的body是乱码呀,还有个问题我模拟登陆之后在请求别的url的时候是不是直接用同一个HTTPclient就行了,需要再添加Cookie吗?谢谢~
现在这代码还能登陆吗?我改了账号密码,显示login error
我的也现实login error,后来你解决了吗?
您好,请问,您就是用上面的代码登陆成功的吗?修改了吗?
本文已许久没更新呢,新浪微博变化了加密方法的话,需要更改加密部分的代码
请教一下,代码中的opener有何用处?是用来保存cookie吗?发现你后续代码中并没有使用opener了。如何能够实现完成模拟登录之后保存cookie完成后续访问呢?
楼主人气太旺了,还是赶紧维护一下代码吧!
有空放到github
感谢分享,分析的很细致啊
两年前用易语言模拟登录的时候来过这里,现在在学python,又来到这里了,呵呵
找了一下最新加密的语句,没有细看,明天再看看
d.su = sinaSSOEncoder.base64.encode(urlencode(a));
me.service && (d.service = me.service);
if (me.loginType & rsa && me.servertime && sinaSSOEncoder && sinaSSOEncoder.RSAKey) {
d.servertime = me.servertime;
d.nonce = me.nonce;
d.pwencode = "rsa2";
d.rsakv = me.rsakv;
var e = new sinaSSOEncoder.RSAKey;
e.setPublic(me.rsaPubkey, "10001");
b = e.encrypt([me.servertime, me.nonce].join("\t") + "\n" + b)
} else if (me.loginType & wsse && me.servertime && sinaSSOEncoder && sinaSSOEncoder.hex_sha1) {
d.servertime = me.servertime;
d.nonce = me.nonce;
d.pwencode = "wsse";
b = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(b)) + me.servertime + me.nonce)
汗,弄了一晚上,一直是4049请输入验证码
可是在前面prelogin的时候checkpin返回的showpin=0,也就是不需要验证码
真恼火
解决了,说来惭愧,在微博账号设置里增加一下在以下地点登录不需要验证码即可
话说我看最新的http://login.sina.co m.cn/sso/ssologin.js 里关于加密的语句跟你这里列出来的一样,但是我具体加密之后得到的sp值和httpfox里观察到的值不一样啊。。你这里有额外进行什么处理了么?跪求解答啊。。。
后来我发现虽然我测试算出来的和观察到的不一样,但是我代码最终还是能正常模拟登陆。。。不知道为啥。。。
里面有时间戳加入运算,每次都是不一样的
编程新手求解答:请问这个代码还能用么?为什么我怎么改都不行啊。课设急需,求解答,谢谢谢谢谢谢!!
一直是login error,是加密算法的问题么?还想请问url是怎么看的?万分感谢!!