上次发了一篇文章,题目叫做《Python使用cookielib和urllib2模拟登陆新浪微博并抓取数据》,里面的代码请不要怀疑,我测试过它是正确的。
新浪微博的模拟登陆,有个前提条件,你用新浪微博账号登陆的时候,新浪没有提示你输入验证码。若需要输入验证码,不好意思这里不作处理,你可以用以下几种方法解决验证码问题:
1、用图片识别软件识别,不过识别正确率会很低
2、登陆的时候如果需要验证码,我们的自己的程序就弹出验证码的图片,自己手工输入
3、外包给验证码输入公司,比如100元,把图片传过去,他给你送回文字结果10000个
程序运行到了后面,我提到urllib2里面的cookie已经存放了我们请求任何页面需要的数据,因此可以用urllib2请求任何页面、发微薄、投票实现任何事情,详细见如下代码,猥琐的分隔栏下面是新增的内容,为了方便,我把上次的代码一起贴出来了,代码注释很给力,大家可以看一看,本代码测试成功:
# coding=utf8 import urllib import urllib2 import cookielib import base64 import re import json import hashlib import time from django.template.defaultfilters import urlencode # 获取一个保存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 = 'xxx' # 微博密码 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' , 'Referer':'http://vote.weibo.com/vid=1890981' } # 到此已经能够使用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,可以换成任意的地址,都能把内容读取下来 #--------------------------------------------------------- # 以下为2012年7月25日21新增: # 对一个投票页面进行投票 #--------------------------------------------------------- # 首先请求一下投票页面,这样做只是为了该页面会返回cookie,我们要保存cookie res = urllib2.urlopen('http://vote.weibo.com/vid=1890981') # 分析了投票的流程,需要如下几个参数的值 votedata = { 'item':'1', 'share':'1', 'poll_id':'1890981', 'poll_category':'0', '_t':'0' } # 原文的那个headers少了一项Referer,结果导致投票不成功,所以这里加上 headers_more = {'User-Agent':'Mozilla/5.0 (X11; Linux i686; rv:8.0) Gecko/20100101 Firefox/8.0' , 'Referer':'http://vote.weibo.com/vid=1890981' } # 把投票的参数的值进行编码,用于urllib2请求的时候附带 votedata = urllib.urlencode(votedata) # URL、数据、请求HTTP头,我们伪造了一个请求包 req = urllib2.Request( url='http://vote.weibo.com/poll/joined', data=votedata, headers=headers_more ) # 发出请求包,到页面看一看,投票OK result = urllib2.urlopen(req) # 把返回的内容存下来看看,其实这一步无必要了 text = result.read() f = open('out.txt', 'w') f.write(text) print 'ok' main()
报错
好久没来了,过来转转