新浪微博数据挖掘菜谱之一: 登录篇 (API)

#!/usr/bin/python
# -*- coding: utf-8 -*-

'''
Created on 2014-12-28
@author: beyondzhou
@name: login.py
'''

import re, json
import urllib, urllib2, urllib3, cookielib
import base64, rsa, binascii # encrypt
from weibo import APIClient

class SmartRedirectHandler(urllib2.HTTPRedirectHandler):
    def http_error_301(self, cls, req, fp, code, msg, headers):
        result = urllib2.HTTPRedirectHandler.http_error_301(cls, req, fp, code, msg, headers)
        result.status = code
        return result

    def http_error_302(self, cls, req, fp, code, msg, headers):
        result = urllib2.HTTPRedirectHandler.http_error_302(cls, req, fp, code, msg, headers)
        result.status = code
        return result

def get_cookie():
    cookies = cookielib.CookieJar()
    return urllib2.HTTPCookieProcessor(cookies)

def get_opener(proxy=False):
    rv=urllib2.build_opener(get_cookie(), SmartRedirectHandler())
    rv.addheaders = [('User-agent', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)')]
    return rv

class SinaAPI():
    def __init__(self, CALLBACK_URL, APP_KEY, REDIRECT_URL, USER_ID, USER_PSWD):
        self.CALLBACK_URL = CALLBACK_URL
        self.APP_KEY = APP_KEY
        self.REDIRECT_URL = REDIRECT_URL
        self.USER_ID = USER_ID
        self.USER_PSWD = USER_PSWD
        self.http = urllib3.PoolManager()

    def get_username(self, USER_ID):
        # The Encryption Algorithm of username
        # ssologin.js : ah.su=sinaSSOEncoder.base64.encode(m(aj));
        USER_ID_ = urllib.quote(USER_ID) # encode username, avoid error refer:@ &
        su = base64.encodestring(USER_ID_)[:-1]
        return su

    def get_password_rsa(self, USER_PSWD, PUBKEY, servertime, nonce):
        # rsa Encrypt :  #when pwencode = "rsa2"
        rsaPubkey = int(PUBKEY, 16)#pubkey from 16 to 10
        key_1 = int('10001', 16) #10001 to 65537
        key = rsa.PublicKey(rsaPubkey, key_1) #
        message = str(servertime) + "\t" + str(nonce) + "\n" + str(USER_PSWD)
        passwd = rsa.encrypt(message, key)
        passwd = binascii.b2a_hex(passwd) #to 16
        return passwd

    def get_parameter(self):
        su = self.get_username(self.USER_ID)
        url = "https://login.sina.com.cn/sso/prelogin.php?entry=openapi&callback=sinaSSOController.preloginCallBack&su="+su+"&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.15)"
        r = self.http.request('GET', url)
        p = re.compile('\((.*)\)')
        json_data = p.search(r.data).group(1)
        data = json.loads(json_data)

        PUBKEY = data['pubkey']
        pcid = data['pcid']
        servertime = str(data['servertime'])
        nonce = data['nonce']
        rsakv = str(data['rsakv'])
        sp = self.get_password_rsa(self.USER_PSWD, PUBKEY, servertime, nonce)

        #print pcid; print servertime; print nonce; print rsakv; print sp; print su
        return pcid, servertime, nonce, rsakv, sp, su

    def get_ticket(self):
        pcid, servertime, nonce, rsakv, sp, su = self.get_parameter()
        fields = urllib.urlencode({
            'entry'        : 'openapi',
            'gateway'      : '1',
            'from'         : '',
            'savestate'    : '0',
            'useticket'    : '1',
            'pagerefer'    :'',
            'pcid'         : pcid,
            'ct'           : '1800',
            's'            : '1',
            'vsnf'         : '1',
            'vsnval'       : '',
            'door'         : '',
            'appkey'       : 'kxR5R',
            'su'           : su,
            'service'      : 'miniblog',
            'servertime'   : servertime,
            'nonce'        : nonce,
            'pwencode'     : 'rsa2',
            'rsakv'        : rsakv,
            'sp'           : sp,
            'sr'           : '1680*1050',
            'encoding'     : 'UTF-8',
            'cdult'        : '2',
            'domain'       : 'weibo.com',
            'prelt'        : '0',
            'returntype'   : 'TEXT',
        })
        headers = {
                   #"Request": "POST /sso/login.php?client=ssologin.js(v1.4.15)&_=1400652171542 HTTP/1.1",
                   #"Accept": "*/*",
                   "Content-Type": "application/x-www-form-urlencoded",
                   #"Referer": self.CALLBACK_URL,
                   #"Accept-Language": "zh-CN",
                   #"Origin": "https://api.weibo.com",
                   #"Accept-Encoding": "gzip, deflate",
                   #"User-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; EIE10;ZHCNMSE; rv:11.0) like Gecko",
                   #"Host": "login.sina.com.cn",
                   #"Connection": "Keep-Alive",
                   #"Cache-Control": "no-cache",
                   }
        url = "https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)"
        req = urllib2.Request(url, fields, headers)
        f = urllib2.urlopen(req)
        data = json.loads(f.read())
        return data["ticket"]

    def get_code_Security(self):
        ticket = self.get_ticket()
        fields = urllib.urlencode({
            'action': 'submit', # must
            'display': 'default',
            'withOfficalFlag': '0', # must
            'quick_auth': 'null',
            'withOfficalAccount': '',
            'scope': '',
            'ticket': ticket, # must
            'isLoginSina': '',
            'response_type': 'code', # must
            'regCallback': 'https://api.weibo.com/2/oauth2/authorize?client_id='+self.APP_KEY+'&response_type=code&display=default&redirect_uri='+self.REDIRECT_URL+'&from=&with_cookie=',
            'redirect_uri': self.REDIRECT_URL, # must
            'client_id': self.APP_KEY, # must
            'appkey62': 'kxR5R',
            'state': '', # must
            'verifyToken': 'null',
            'from': '', # must
            'userId': "", # do not need enter userId
            'passwd': "", # do not need enter password
            })
        LOGIN_URL = 'https://api.weibo.com/oauth2/authorize'
        headers = {"User-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; EIE10;ZHCNMSE; rv:11.0) like Gecko",
                   "Referer": self.CALLBACK_URL,
                   "Content-Type": "application/x-www-form-urlencoded",
                   }
        req = urllib2.Request(LOGIN_URL, fields, headers)
        req_ =urllib2.urlopen(req)
        return_redirect_uri = req_.geturl()

        print 'return_redirect_uri:', return_redirect_uri
        code = re.findall(r"(?<=code%3D).{32}|(?<=code=).{32}|(?<=code%253D).{32}", return_redirect_uri) # url is formatted with %3D or=
        return code 

    def get_code_NS(self):
        fields = urllib.urlencode({
            'action': 'submit', # must
            'display': 'default',
            'withOfficalFlag': '0', # must
            'quick_auth': 'null',
            'withOfficalAccount': '',
            'scope': '',
            'ticket': '', # must
            'isLoginSina': '',
            'response_type': 'code', # must
            'regCallback': '',
            'redirect_uri': self.REDIRECT_URL, # must
            'client_id': self.APP_KEY, # must
            'appkey62': 'kxR5R',
            'state': '', # must
            'verifyToken': 'null',
            'from': '', # must
            'userId': self.USER_ID, # must
            'passwd': self.USER_PSWD, # must
            })
        LOGIN_URL = 'https://api.weibo.com/oauth2/authorize'
        headers = {"User-agent": "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; EIE10;ZHCNMSE; rv:11.0) like Gecko",
                   "Referer": self.CALLBACK_URL,
                   "Content-Type": "application/x-www-form-urlencoded",
                   }
        r = urllib2.Request(LOGIN_URL, fields, headers)
        opener = get_opener(False)
        urllib2.install_opener(opener)
        try:
            f = opener.open(r)
            return_redirect_uri = f.url
            print "NS1", return_redirect_uri
        except urllib2.HTTPError, e:
            return_redirect_uri = e.geturl()
            print "NS2", return_redirect_uri
        # get the code
        #code = return_redirect_uri.split('=')[1]
        # re-generate with regexp expression
        code = re.findall(r"(?<=code%3D).{32}|(?<=code=).{32}", return_redirect_uri)
        print code
        return code 

def weibo_login(): 

    # sina weibo basic secret information
    APP_KEY = u'' # app key
    APP_SECRET = u'' # app secret
    REDIRECT_URL = ''
    USER_NAME = ''
    USER_PASSWD = ''

    client = APIClient(app_key=APP_KEY, app_secret=APP_SECRET, redirect_uri=REDIRECT_URL)
    CALLBACK_URL = client.get_authorize_url()
    print 'callback_url:', CALLBACK_URL
    API = SinaAPI(CALLBACK_URL, APP_KEY, REDIRECT_URL, USER_NAME, USER_PASSWD)
    code = API.get_code_Security()
    print 'code:', code
    requests = client.request_access_token(code)
    access_token = requests.access_token
    expires_in = requests.expires_in  

    # access_token
    client.set_access_token(access_token, expires_in)
    return client

if __name__ == '__main__':

    # get weibo_api to access sina api
    weibo_api = weibo_login()
    print 'weibo_api:', weibo_api

    # get 200 public weibo
    statuses = weibo_api.statuses.public_timeline.get(count=200)
    print json.dumps(statuses, indent=1)

Result:

code: ['514b806e619c320b7b1ed85ec0d9880a']
weibo_api: <weibo.APIClient object at 0x027786D0>
{
 "interval": 0,
 "hasvisible": false,
 "total_number": 2,
 "previous_cursor": 0,
 "next_cursor": 0,
 "statuses": [
  {
   "reposts_count": 0,
   "truncated": false,
   "text": "\u7238\u7238\uff0c\u5c31\u50cf\u8fd9\u4e48\u75bc\u2026\u2026",
   "visible": {
    "type": 0,
    "list_id": 0
   },
   "in_reply_to_status_id": "",
   "bmiddle_pic": "http://ww1.sinaimg.cn/bmiddle/dea230dbjw1enp0tkfoy7j20cs281dm7.jpg",
   "id": 3792648903463407,
   "thumbnail_pic": "http://ww1.sinaimg.cn/thumbnail/dea230dbjw1enp0tkfoy7j20cs281dm7.jpg",
   "mid": "3792648903463407",
   "source": "<a href=\"http://app.weibo.com/t/feed/3auC5p\" rel=\"nofollow\">\u76ae\u76ae\u65f6\u5149\u673a</a>",
   "attitudes_count": 0,
   "in_reply_to_screen_name": "",
   "pic_urls": [
    {
     "thumbnail_pic": "http://ww1.sinaimg.cn/thumbnail/dea230dbjw1enp0tkfoy7j20cs281dm7.jpg"
    }
   ],
   "in_reply_to_user_id": "",
   "darwin_tags": [],
   "favorited": false,
   "original_pic": "http://ww1.sinaimg.cn/large/dea230dbjw1enp0tkfoy7j20cs281dm7.jpg",
   "idstr": "3792648903463407",
   "source_type": 1,
   "user": {
    "bi_followers_count": 310,
    "domain": "",
    "avatar_large": "http://tp4.sinaimg.cn/3735171291/180/40031850543/0",
    "verified_source": "",
    "ptype": 0,
    "statuses_count": 1589,
    "allow_all_comment": true,
    "id": 3735171291,
    "verified_reason_url": "",
    "city": "1000",
    "province": "50",
    "credit_score": 80,
    "block_app": 0,
    "follow_me": false,
    "verified_reason": "",
    "followers_count": 563,
    "location": "\u91cd\u5e86",
    "verified_trade": "",
    "mbtype": 0,
    "verified_source_url": "",
    "profile_url": "u/3735171291",
    "block_word": 0,
    "avatar_hd": "http://tp4.sinaimg.cn/3735171291/180/40031850543/0",
    "star": 0,
    "description": "",
    "friends_count": 772,
    "online_status": 0,
    "mbrank": 0,
    "idstr": "3735171291",
    "profile_image_url": "http://tp4.sinaimg.cn/3735171291/50/40031850543/0",
    "allow_all_act_msg": false,
    "verified": false,
    "geo_enabled": true,
    "class": 1,
    "screen_name": "Cz_\u5a77\u7ea6",
    "lang": "zh-cn",
    "weihao": "",
    "remark": "",
    "favourites_count": 0,
    "name": "Cz_\u5a77\u7ea6",
    "url": "",
    "gender": "f",
    "created_at": "Thu Aug 22 12:14:23 +0800 2013",
    "verified_type": -1,
    "following": false,
    "pagefriends_count": 0,
    "urank": 8
   },
   "geo": null,
   "created_at": "Sun Dec 28 07:03:45 +0800 2014",
   "mlevel": 0,
   "comments_count": 0
  },
  {
   "reposts_count": 0,
   "truncated": false,
   "text": "#\u60c5\u4fc2\u963f\u54f2#\u4e70\u4e00\u5f20\u6f14\u5531\u4f1a\u95e8\u7968\uff0c\u5e26\u4e0a\u5c0f\u4f19\u4f34\uff0c\u7a7f\u7740\u4f1a\u670d\u62ff\u7740\u4f60\u7684\u4e13\u8f91\u548c\u71c8\u724c\u5954\u8d74\uff0c\u4e0d\u7528\u79bb\u4f60\u5f88\u8fd1\u54ea\u6015\u5750\u5728\u89d2\u843d\uff0c\u54ea\u6015\u4e0d\u80fd\u770b\u6e05\u53f0\u4e0a\u7684\u4f60\uff0c\u54ea\u6015\u4f60\u4e0d\u77e5\u9053\u4eba\u7fa4\u8fd8\u6709\u4e00\u4e2a\u6211\u3002\u4f46\u53ea\u8981\u80fd\u542c\u89c1\u5e38\u5e38\u5728\u8033\u673a\u91cc\u51fa\u73b0\u7684\u90a3\u4e2a\u58f0\u97f3\uff0c\u53ea\u8981\u80fd\u5750\u5728\u8fd9\u91cc\u4e00\u8d77\u4e3a\u4f60\u5450\u558a\uff0c\u53ea\u8981\u80fd\u548c\u4f60\u7ad9\u5728\u540c\u6837\u7684\u5929\u7a7a\u4e0b\u547c\u5438\u540c\u4e00\u7247\u6c27\u6c14\uff0c\u8fd9\u6837\u5c31\u5df2\u7ecf\u5f88\u597d\u4e86",
   "visible": {
    "type": 0,
    "list_id": 0
   },
   "in_reply_to_status_id": "",
   "bmiddle_pic": "http://ww4.sinaimg.cn/bmiddle/5d16267bjw1enp0tkhsxhj20c80klq39.jpg",
   "id": 3792648903463367,
   "thumbnail_pic": "http://ww4.sinaimg.cn/thumbnail/5d16267bjw1enp0tkhsxhj20c80klq39.jpg",
   "mid": "3792648903463367",
   "source": "<a href=\"http://app.weibo.com/t/feed/4P1GTP\" rel=\"nofollow\">\u6735\u552f\u5973\u6027\u624b\u673a</a>",
   "attitudes_count": 0,
   "in_reply_to_screen_name": "",
   "pic_urls": [
    {
     "thumbnail_pic": "http://ww4.sinaimg.cn/thumbnail/5d16267bjw1enp0tkhsxhj20c80klq39.jpg"
    }
   ],
   "in_reply_to_user_id": "",
   "darwin_tags": [],
   "favorited": false,
   "original_pic": "http://ww4.sinaimg.cn/large/5d16267bjw1enp0tkhsxhj20c80klq39.jpg",
   "idstr": "3792648903463367",
   "source_type": 1,
   "user": {
    "bi_followers_count": 206,
    "domain": "",
    "avatar_large": "http://tp4.sinaimg.cn/1561732731/180/5709043270/0",
    "verified_source": "",
    "ptype": 0,
    "statuses_count": 57711,
    "allow_all_comment": false,
    "id": 1561732731,
    "verified_reason_url": "",
    "city": "8",
    "province": "37",
    "credit_score": 80,
    "block_app": 0,
    "follow_me": false,
    "verified_reason": "",
    "followers_count": 1487,
    "location": "\u5c71\u4e1c \u6d4e\u5b81",
    "verified_trade": "",
    "mbtype": 0,
    "verified_source_url": "",
    "profile_url": "u/1561732731",
    "block_word": 0,
    "avatar_hd": "http://ww3.sinaimg.cn/crop.100.0.318.318.1024/5d16267bjw8ellhct6ii9j20ef08ujs6.jpg",
    "star": 0,
    "description": "\u672c\u547d\u3001\u7537\u795e\uff1a\u5f35\u4fe1\u54f2/\u5973\u795e\uff1a\u6797\u4f9d\u6668/\u5076\u50cf:\u74ca\u7464\u963f\u59e8/\u559c\u6b61\u7684\u9b54\u8853\u5e2b:\u5289\u8b19/\u559c\u6b61\u53f0\u7063\u5287 \u91d1\u5eb8\u5287/",
    "friends_count": 951,
    "online_status": 1,
    "mbrank": 0,
    "idstr": "1561732731",
    "profile_image_url": "http://tp4.sinaimg.cn/1561732731/50/5709043270/0",
    "allow_all_act_msg": false,
    "verified": false,
    "geo_enabled": true,
    "class": 1,
    "screen_name": "\u88d9\u89d2\u98db\u63da0326\u4f9d\u5fc3\u54f2\u610f",
    "lang": "zh-tw",
    "weihao": "",
    "remark": "",
    "favourites_count": 22,
    "name": "\u88d9\u89d2\u98db\u63da0326\u4f9d\u5fc3\u54f2\u610f",
    "url": "http://blog.sina.com.cn/qunjiao2quan",
    "gender": "f",
    "created_at": "Sun Nov 01 17:38:36 +0800 2009",
    "verified_type": 220,
    "following": false,
    "pagefriends_count": 0,
    "urank": 23
   },
   "geo": null,
   "created_at": "Sun Dec 28 07:03:45 +0800 2014",
   "mlevel": 0,
   "comments_count": 0
  }
 ]
}
时间: 2024-07-30 03:24:17

新浪微博数据挖掘菜谱之一: 登录篇 (API)的相关文章

新浪微博数据挖掘菜谱之三: 搜索篇 (selenium)

#!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-12-30 @author: beyondzhou @name: decode_search_entities.py ''' # Decode entities from search result def decode_search_entities(): # import from search import weibo_search from entities imp

新浪微博数据挖掘菜谱之二: 话题篇 (selenium)

#!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2014-12-29 @author: beyondzhou @name: discovery_trend_topic.py ''' # Get trend topic of sina discovery def discovery_trend_topic(): from discovery import weibo_discovery from entities import di

关于新浪微博注销后自动登录的问题

最近程序中需要做分享功能,腾讯的的OK,但新浪的注销后,再次点击时,本来应该进入到登录的授权页面,webview形式出现.但结果每次再进入时,会自动登录上次注销的号. 查了相关资料后,发现有两种解决办: 1: 因为只清除了登录数据,但是uiwebview的cookie仍然保留在本地,所以需要清除uiwebview的cookie内容,清除方式如下: NSHTTPCookie *cookie;    NSHTTPCookieStorage *storage = [NSHTTPCookieStorag

**15.app后端怎么设计用户登录方案(API权限安全)

在很多app中,都需要用户的登录操作.登录,就需要用到用户名和密码.为了安全起见,暴露明文密码的次数越少越好.怎么能最大程度避免泄露用户的密码呢?在登录后,app后端怎么去验证和维持用户的登录状态呢?在本文中,给出了一套用户登录的解决方案,以供大家参考. 1. 保证登录的安全性,最起码要使用https协议 避免信息的泄露,最简单的方案是所有涉及到安全性的api请求,都必须要使用https协议. HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议

AppDelegate减负之常用三方封装 - 友盟分享 / 三方登录篇

之前完成了 AppDelegate减负之常用三方封装 - 友盟推送篇: http://www.cnblogs.com/zhouxihi/p/7113511.html 今天接着来完成 - 友盟分享和三方登录篇 首先去友盟上面下载SDK, 一般就新浪/微信/QQ  我们都选择精简版 把下载好的SDK添加到项目, 按照开发文档添加libsqlite3.0.tbd到Linked Frameworks, 在Build Settings -> Linking -> Other Linker Flags 添

基于Netty的聊天系统(二)协议定制----登录篇

上一篇文章我们讨论了聊天的基本流程,那么我们现在基于上一篇文章的流程开始定义协议,如果有朋友有更好的建议,可以在下边回复一起学习讨论,我们说登录分为两部分,第一部分为和服务器的连接阶段,第二部分为验证阶段,那么首先我们基于这2个部分来指定协议: 连接阶段: {"id":"xxxx","#":"conn","u":1[email protected]/ios,"v":100} id:客户端

手机第三方新浪微博登录php api实现分析

提供api,POST方式,根据传递过来的微博uid/appkey,判断该用户的ID是否在自己的数据库中. 如果有,直接登录返回用户登录api的json. 如果没有,就将该用户的ID+token请求微博用户信息api:http://open.weibo.com/wiki/2/users/show,根据返回的用户信息json数据在数据库中创建新用户.再执行登录,返回用户登录的json. 使用微博 php sdk,根据微博返回的token值,获得用户信息. 微博授权返回post参数 { "uid&qu

新浪微博的账号登录及api操作

1.sina.php <?php /** * PHP Library for weibo.com * * @author PiscDong (http://www.piscdong.com/) */ class sinaPHP { function __construct($client_id, $client_secret, $access_token=NULL){ $this->client_id=$client_id; $this->client_secret=$client_se

新浪微博数据挖掘食谱之六: 元素篇 (提取微博元素)

#!/usr/bin/python # -*- coding: utf-8 -*- ''' Created on 2015-1-2 @author: beyondzhou @name: extract_weibo_entities.py ''' # Extract entities of sina weibo def extract_weibo_entities(): # import from login import weibo_login from statuses import extr