这个方法抓下来的网页,得不到相册图片,新浪要js动态生成图片,解决方法可以是:1. 本地用webkit跑抓下来的js;2.抓移动版微博的静态相册。 但都暂时未实现,欢迎回帖好方法,以下是转文。
-----------------------------------------
我们都知道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,可以做抓数据等任何事情,你甚至可以写一个多线程的爬虫来爬遍新浪微博,我一直有这个想法,可从来没有实现。如果您有什么进展,请联系我共同进步。