您的位置:首页 > 编程语言 > Python开发

python登录新浪微博并抓取内容

2014-05-02 10:31 369 查看
一直听说python简单易用,最近看了一下python,发现是简单不少,语法比较随便,用比较多的库拿来直接用。用来写爬虫很简单,网上用很多例子,糗百,豆瓣妹子和百度贴吧等,不过这些网站登录起来比较简单。也有一些比较麻烦的,例如新浪微博,下面我就把我自己弄得一个新浪微博的爬虫整理一下。。

所用工具:Python 2.7.6 HttpFox

Python 2.7.6 : 编译环境

HttpFox :一款http协议分析插件,分析页面请求和响应的时间、内容、以及浏览器用到的COOKIE等(具体用法这里就不多介绍)

第一步:

通过有关资料可知,新浪微博的登录的过程比较麻烦,客户端用js预先对用户名、密码都进行了加密,
而且在POST之前会GET 一组参数,这也将作为POST_DATA 的一部分,所以就不能用通常的那种简单方法来模拟POST 登录

这里我们用HttpFox插件来验证一下。



如图,(1)先get一组数据,然后(2)再post

get的内容:



分别为:retcode,servertime,pcid,nonce,pubkey,rsakv,showpin,exectime,其中servertime,nonce字段用于对密码的加密,并且原封不动的posh回去,这些将在post方法中看到;pubkey和rsakv用于rsa2加密。

post的内容(POST Data):



我们发现有很多字段,其中su,sp为加密过后的用户名和密码,servertime和nonce是get得到内容,并且由pwencode 字段可知,加密方式为rsa2

经过第一步的分析,下面我们用代码来一步一步的实现:

第二步,首先实现get:新建getdata.py文件

#-*- coding: UTF-8 -*-
import urllib2
import re
import json
import string

class GET_DATA:
def __init__(self):
#获取servertime ,nonce ,publey,rsakv的网址
self.url = 'http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.11)&_=1398760051250'

def get_data(self):
data = urllib2.urlopen(self.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']
pubkey = data['pubkey']
rsakv = data['rsakv']
return nonce,rsakv,servertime,pubkey
except:
print '不能获取servertime 和 data'
return None
注:self.url 的网址为第一步HttpFox插件中显示的get方法所指向的URL;

get_data方法返回servertime,nonce等字段

第三步,对用户名和密码进行加密,新建datadeal.py文件

# -*- coding:UTF-8 -*-
import urllib
import hashlib
import rsa
import binascii
import string
import base64
import getdata

class data_deal:
def __init__(self,username,password):
self.username = username
self.password = password
self.gd = getdata.GET_DATA()
self.nonce,self.rsakv,self.servertime,self.pubkey = self.gd.get_data()

#获取nonce
def get_nonce(self):
return self.nonce

#获取servername
def get_servername(self):
return self.servertime

#获取 rsakv
def get_rsakv(self):
return self.rsakv

#username 经过了BASE64 计算:
#username = base64.encodestring( urllib.quote(username) )[:-1]
def get_username(self):
username_ = urllib.quote(self.username)
username = base64.encodestring(username_)[:-1]
return username

#password经过rsa加密
def get_pwd(self):
rsaPublickey = int(self.pubkey,16)
key = rsa.PublicKey(rsaPublickey,65537)

message = str(self.servertime) + '\t' + str(self.nonce) + '\n' + str(self.password)
pwd_ = rsa.encrypt(message,key)
pwd = binascii.b2a_hex(pwd_)
return pwd

def print_data(self):
print self.nonce
print self.rsakv
print self.servertime
print self.pubkey


第四步,实现登录功能,先贴代码,新建login.py文件

# -*- coding:UTF-8 -*-
import datadeal
import urllib
import urllib2
import cookielib
import re

class log_in:
def __init__(self,username,password):
self.dd = datadeal.data_deal(username,password)
self.url = 'http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.11)'

#登录
def login(self):
cj = cookielib.LWPCookieJar()
cookie_support = urllib2.HTTPCookieProcessor(cj)
opener = urllib2.build_opener(cookie_support,urllib2.HTTPHandler)
urllib2.install_opener(opener)
post_data = {
'entry' : 'weibo',
'gateway' : '1',
'from'  : '',
'savestate' : '7',
'useticket' : '1',
'pagerefer' : 'http://weibo.com/signup/signup.php',
'vsnf'   : '1',
'su'  : '',
'service' : 'miniblog',
'servertime': '',
'nonce': '',
'pwencode': 'rsa2',
'rsakv' : '',
'sp' :'',
'encoding' : 'UTF-8',
'prelt' : '115',
'url' : 'http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack',
'returntype' : 'META'
}
post_data['servertime'] = self.dd.get_servername()
post_data['nonce'] = self.dd.get_nonce()
post_data['su'] = self.dd.get_username()
post_data['sp'] = self.dd.get_pwd()
post_data['rsakv'] = self.dd.get_rsakv()

post_data = urllib.urlencode(post_data)
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1;rv:26.0) Gecko/20100101 Firefox/26.0'}
req = urllib2.Request(
url = self.url,
data = post_data,
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 u'匹配url:'
print login_url
html = urllib2.urlopen(login_url)
data = html.read()
print u'登录成功!'
print data
except:
print u'登录失败!'
注:self.url 为HttpFox插件POST方法后显示的URL

post_data根据插件POST Data中的内容构造,将其中的servertime,nonce,su,sp字段替换成经过处理的数据

至此,新浪微博的登录工作已经结束

最后:测试,新建main.py

# -*- coding: UTF-8 -*-
import login
import urllib2

username = raw_input(u'请输入用户名:')
password = raw_input(u'请输入密码:')
mylog = login.log_in(username,password)
mylog.login()

##测试登录成功
myUrl = '你的微薄主页URL'
res = urllib2.urlopen(myUrl)
data = res.read()
print data


参考资料(python的基础):http://blog.csdn.net/column/details/why-bug.html

源代码下载地址:https://github.com/lijuntao/sina_weibo_login
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: