之前写过在python中使用weibo API的方法,见这里,但是因为weibo API有频率限制,不够目前需求使用,所以通过爬虫模拟登录weibo进行直接抓取还是很有必要的,第一步要做的事情就是模拟登录过程。
weibo的登录方法一直在变,不知道现在的方法还能使用多久。
目前登录使用的是RSA加密的方式,总体来看步骤分为三步:
- 访问预登录地址,获取servertime、nonce和RSA公钥
- 访问认证地址,发送编码后的用户名和RSA加密过的密码,获得跳转地址
- 访问获得的地址,获取到登录cookie,登录完成
代码如下,注释比较少,主要是__login()函数内的过程,需要安装rsa包,easy_install即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# -*- coding: utf-8 -*- import urllib2, urllib, cookielib import re, json, base64 import rsa, binascii url_prelogin = 'http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.5)&_=1364875106625' url_login = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.5)' class Toy(object): def fecth_page(self, url = 'http://weibo.com', data = None): return self.__opener.open(url, data) def __init__(self, username, password): self.__username = username self.__password = password cj = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) opener.addheaders = [('User-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:19.0) Gecko/20100101 Firefox/19.0')] self.__opener = opener self.__login() def __encode_passwd(self, pwd, servertime, nonce, pubkey): rsaPublickey = int(pubkey, 16) key = rsa.PublicKey(rsaPublickey, 65537) #创建公钥 message = str(servertime) + '\t' + str(nonce) + '\n' + str(pwd)#拼接明文 js加密文件中得到 passwd = rsa.encrypt(message, key)#加密 passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。 return passwd def __encode_username(self, username): username = urllib.quote(username) username = base64.encodestring(username)[:-1] return username def __prelogin(self): html = self.__opener.open(url_prelogin).read() json_data = re.search('\((.*)\)', html).group(1) data = json.loads(json_data) servertime = data['servertime'] nonce = data['nonce'] pubkey = data['pubkey'] rsakv = data['rsakv'] return servertime, nonce, pubkey, rsakv def __login(self): (servertime, nonce, pubkey, rsakv) = self.__prelogin() sp = self.__encode_passwd(self.__password, servertime, nonce, pubkey) su = self.__encode_username(self.__username) postdata = { 'entry': 'weibo', 'gateway': '1', 'from': '', 'savestate': '7', 'userticket': '1', 'ssosimplelogin': '1', 'vsnf': '1', 'vsnval': '', 'su': su, 'service': 'miniblog', 'servertime': servertime, 'nonce': nonce, 'pwencode': 'rsa2', 'sp': sp, 'encoding': 'UTF-8', 'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack', 'returntype': 'META', 'rsakv' : rsakv, } postdata = urllib.urlencode(postdata) html = self.__opener.open(url_login, postdata).read() url_final = re.search('location\.replace\(\"(.*?)\"\)', html).group(1) self.__opener.open(url_final) |