我们都知道HTTP是无连接的状态协议,但是客户端和服务器端需要保持一些相互信息,比如cookie,有了cookie,服务器才能知道刚才是这个用户登录了网站,才会给予客户端访问一些页面的权限。
用浏览器登录新浪微博,必须先登录,登陆成功后,打开其他的网页才能够访问。用程序登录新浪微博或其他验证网站,关键点也在于需要保存cookie,之后附带cookie再来访问网站,才能够达到效果。
这里就需要Python的cookielib和urllib2等的配合,将cookielib绑定到urllib2在一起,就能够在请求网页的时候附带cookie。
具体做法,首先第一步,用firefox的httpfox插件,在浏览器衷开始浏览新浪微博首页,然后登陆,从httpfox的记录中,查看每一步发送了那些数据请求了那个URL;之后再python里面,模拟这个过程,用urllib2.urlopen发送用户名密码到登陆页面,获取登陆后的cookie,之后访问其他页面,获取微博数据。
具体代码,来自豆瓣的一篇文章:地址
本人加了点注释,欢迎大家一起品尝该同学的完美代码:
# coding=utf8 import urllib import urllib2 import cookielib import base64 import re import json import hashlib # 获取一个保存cookie的对象 cj = cookielib.LWPCookieJar() # 将一个保存cookie对象,和一个HTTP的cookie的处理器绑定 cookie_support = urllib2.HTTPCookieProcessor(cj) # 创建一个opener,将保存了cookie的http处理器,还有设置一个handler用于处理http的URL的打开 opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler) # 将包含了cookie、http处理器、http的handler的资源和urllib2对象板顶在一起 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 main(): username = 'www.crazyant.net' # 微博账号 pwd = 'xxxx' # 微博密码 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'} # 其实到了这里,已经能够使用urllib2请求新浪任何的内容了,这里已经登陆成功了 req = urllib2.Request( url=url, data=postdata, headers=headers ) result = urllib2.urlopen(req) text = result.read() # print text p = re.compile('location\.replace\(\'(.*?)\'\)') try: login_url = p.search(text).group(1) print login_url # print login_url urllib2.urlopen(login_url) print "login success" except: print 'Login error!' # 测试读取数据,下面的URL,可以换成任意的地址,都能把内容读取下来 req = urllib2.Request(url='http://e.weibo.com/aj/mblog/mbloglist?page=1&count=15&max_id=3463810566724276&pre_page=1&end_id=3458270641877724&pagebar=1&_k=134138430655960&uid=2383944094&_t=0&__rnd=1341384513840',) result = urllib2.urlopen(req) text = result.read() print len(result.read()) # unicode(eval(b),"utf-8") print eval("u'''" + text + "'''") main()
其实获取了模拟登陆后的urllib2,可以做抓数据等任何事情,你甚至可以写一个多线程的爬虫来爬遍新浪微博,我一直有这个想法,可从来没有实现。如果您有什么进展,请联系我共同进步。
测试了一下。显示login error。 print出来登录内容。提示retcode=4049错误,是要输入验证码。你有遇到吗
貌似现在抓取不了
可以解析图片内容,加上验证码。这要看它的图片弄得怎么样了。。
问一下,这个网页是怎么获取我的姓名的?
我也在做类似的工作~希望多交流
我也在做类似的工作,hope多交流
我试了,可以使用的。代码里的微博账号填写邮箱。给点证据:dhcp-128-194-161-127:~] laocubu% python sinablog.py http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack&ssosavestate=1358630049&ticket=ST-MjAxMDM0MTY4Nw==-1358025249-gz-2EBACFFF073CA3B261FECED20166811B&retcode=0login success0{“key”:”134138430655960″,”code”:”100000″,”msg”:””,”data”:” 【堪培拉天气】今日天气预报:多云;最高气温37°,最低气温20°;降水概率10%;【更多澳洲本土信息,资讯,生活,潮流,时尚尽在澳洲千百度http://t.cn/zOq3IZN</a>】</p> </li>
可能是你用qq连接该网站登陆的。你的qq里用了真实姓名。
楼主,我很想知道,你是怎么知道新浪的hash加密的?通过什么方式分析出来是这样加密的?
这个是从网上搜出来的~~呵呵,找了好久,在一个论坛有个帖子有人这么说的,我也忘了出处了
刚才发现不能登录了,几个小时前还可以。。。
现在登陆不了了。 看登录加密方法变成了RSA的了。 但是使用RSA加密,还是不行
请问你现在是怎么登录新浪微博的阿?还有就是你是使用什么软件查看登录加密方法的阿
RSA吗,那客户端如果能获取公钥的话,也没什么问题吧
sinaSSOEncoder.RSAKey){
d["servertime"]=k.servertime;
d["nonce"]=k.nonce;
d["pwencode"]="rsa2";
d["rsakv"]=k.rsakv;
var e=new sinaSSOEncoder.RSAKey();
e.setPublic(k.rsaPubkey,’10001′);
b=e.encrypt([k.servertime,k.nonce].join("t")+"n"+b)
}
else if((k.loginType&M)&&k.servertime&&sinaSSOEncoder&&sinaSSOEncoder.hex_sha1)
{
d["servertime"]=k.servertime;
d["nonce"]=k.nonce;
d["pwencode"]="wsse";
b=sinaSSOEncoder.hex_sha1(""+sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(b))+k.servertime+k.nonce)
}
d["sp"]=b;
return d
};
这时新的JS文件 不知道楼组有否研究
怎么样阿 你解决这个问题了没阿。。。。js文件里的代码不理解。。。尝试rsa加密几次都没有成功
没搞定啊
python操作rsa,
pubkey = page[‘pubkey’]
n=string.atol(pubkey,16)
pubkey = rsa.PublicKey(n,65537)
passwd = rsa.encrypt(passwd.encode(‘utf-8’), pubkey)
到这一步了,貌似还是不行,求交流,QQ251650053
网上找了篇帖子说是和qqmail的rsa一样,就下了qq的javascript版的rsa模拟了一下,和python的一样,加密文件一直再变。python使用的是easy_install 装的rsa,密文也是每次都不一样,据说是使用了填充,sina的脚本还没研究通,提取出来一直运行错误。交流,QQ2507913981
如果密文没问题的话,就剩对passwd的输出了,用b2a_hex(passwd)处理后正好256位,但登录还是失败。
sina的脚本ssologin.js也模拟运行成功,密文是变化的,难道是加密的方法略有变化?
哥们 谢谢你的思路 终于搞定了
http://tieba.baidu.com/f?ct=335675392&tn=baiduPostBrowser&sc=29841333669&z=2183651157
我把关键部分的代码贴在这里了 可以看看。。
现在不搞这个了,直接用 sqlite3和cookielib加载chrome或firefox的cookies,一劳永逸,随它登录方式怎么变,只要判断一下cookie提交给那些个网址就行了,最多2,3个urlopen就解决了。
求指点
能具体的把你这种模拟登陆的方法的代码贴出来吗,我最近刚学这个
https://github.com/llqbll/web_login
谢谢了啊,你的个人博客的地址是什么呢,加个好友,以后大家多交流
运行后报错:
Traceback (most recent call last):
File "login.py", line 236, in <module>
login_status = login.weibo_login()
File "login.py", line 169, in weibo_login
conn = sqlite3.connect(fileChrome)
sqlite3.OperationalError: unable to open database file
请教大神下,这个问题该怎么解决呢?
QQ:2507913981,,你没注意看注释和说明,首先要有chrome,并且已经成功登录。修改获取cookie的路径
还是报错
87行的result = urllib2.urlopen(req)报错,exceptions.TypeError: must be string or buffer, not dict
请问下“http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBac。。。。。。。。。。。。”这个链接可以从httpfox看到吗,为什么我看不到
你好,我最近模拟登陆也出现了这个问题,请问你解决了吗,是如何解决的。。
貌似我试过在登陆区域不用验证码。还是不行
不错 学习了!
博主写的很好,赞一个,多谢分享了
这里有现成写好的新浪微博爬虫[按微博昵称爬取],可以直接使用,有兴趣的童鞋可以试下
http://www.shenjianshou.cn/index.php?r=market/configDetail&pid=139
I was wondering if you ever considered changing the structure of your site?
Its very well written; I love what youve got to say.
But maybe you could a little more in the
way of content so people could connect with it better.
Youve got an awful lot of text for only having one or 2 pictures.
Maybe you could space it out better?
我是偶然通过百度找到你的博客的,文章写的很详细。