一、基础知识
http://blog.csdn.net/pi9nc/article/details/9734437
二、模拟登录
因为上学期参加了一个大数据比赛,需要抓取数据,所以就想着写个爬虫抓取新浪微博的数据。
当然抓取数据不是漫无目的的,我需要的是根据关键词来抓取相关微博。
正好微博有一个高级搜索功能,不过要获取更多的微博,需要登录,所以这时就需要模拟登录了。
以下代码是通过rsa加密算法模块来模拟的。需要注意的是,新浪有反爬虫的,所以我们登录的时候要伪装成浏览器。
代码不是自己写的,所以文章类型标为转载,因为代码大同小异,所以我就不写咯,里面的一些具体代码和问题解析,我也不一一赘述了,因为模拟登录不是我的重点,下一篇我将跟大家谈一谈登录后的抓取与网页解析部分。至于登录,文章开头的链接中有详细教程,有兴趣的可以看一下。
#! /usr/bin/env python
#coding=utf8
import urllib
import urllib2
import cookielib
import base64
import re
import json
import hashlib
import rsa
import binascii
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': 'rsa2', #加密算法
'sp': '',
'encoding': 'UTF-8',
'prelt': '401',
'rsakv': '',
'url': 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
'returntype': 'META'
}
class WeiboLogin:
def __init__(self, username, password):
self.username = username
self.password = password
def __get_spwd(self):
rsaPublickey = int(self.pubkey, 16)
key = rsa.PublicKey(rsaPublickey, 65537) #创建公钥
message = self.servertime + '\t' + self.nonce + '\n' + self.password #拼接明文js加密文件中得到
passwd = rsa.encrypt(message, key) #加密
passwd = binascii.b2a_hex(passwd) #将加密信息转换为16进制。
return passwd
def __get_suser(self):
username_ = urllib.quote(self.username)
username = base64.encodestring(username_)[:-1]
return username
def __prelogin(self):
prelogin_url = 'http://login.sina.com.cn/sso/prelogin.php?entry=sso&callback=sinaSSOController.preloginCallBack&su=%s&rsakt=mod&client=ssologin.js(v1.4.4)' % self.username
response = urllib2.urlopen(prelogin_url)
p = re.compile(r'\((.*?)\)')
strurl = p.search(response.read()).group(1)
dic = dict(eval(strurl)) #json格式的response
self.pubkey = str(dic.get('pubkey'))
self.servertime = str(dic.get('servertime'))
self.nonce = str(dic.get('nonce'))
self.rsakv = str(dic.get('rsakv'))
def login(self):
url = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)'
try:
self.__prelogin() #预登录
except:
print 'Prelogin Error'
return
global postdata
postdata['servertime'] = self.servertime
postdata['nonce'] = self.nonce
postdata['su'] = self.__get_suser()
postdata['sp'] = self.__get_spwd()
postdata['rsakv'] = self.rsakv
postdata = urllib.urlencode(postdata)
headers = {'User-Agent':'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:37.0) Gecko/20100101 Firefox/37.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)
urllib2.urlopen(login_url)
print "Login Succeed!"
except:
print 'Login Error!'