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

      一直听说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


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值