1. 程式人生 > >python sdk 獲取新浪微博簽到資訊

python sdk 獲取新浪微博簽到資訊

不得不說廖大神這個sdk 在我這個新手看來寫的真是太完美了,介面呼叫寫成動態,封裝授權,返回jsondict 

處理起來實在是方便

# -*- coding: utf-8 -*-

'''
Created on 2016年12月18日

@author: bitwater

基於python2.7
寫了一個類用來獲取poiidlist,
由於sina api的限制,也沒必要多執行緒了,除非.....
我建立了很多帳號,一旦有帳號被limit ,我就捕獲這個異常並重新授權 ( while(1) ) 
api介面穩定行不是很好(可能是因為app_key為認證), 為了防止不可預料的錯誤,當資料量非常大的時候
我儘量每次跑n條後 過幾分鐘再跑 ,參考下面的網站 ,官方說的很不明確限制到底是什麼
http://open.weibo.com/wiki/%E6%8E%A5%E5%8F%A3%E8%AE%BF%E9%97%AE%E9%A2%91%E6%AC%A1%E6%9D%83%E9%99%90

經過反覆測試,post或get可以達到連續萬次請求(應該是極限了),不過這個不穩定

我寫了一個類用來獲取所有的poiid
然後又寫了一個根據poiid list ,獲取使用者資訊的類


'''
import weibo
import codecs
from SinaSDK.PoiidList import PoiidList
import urllib2

class Sina(object):
        
    APP_KEY = [ 
               
               '4051276836',
               '1859650768',
               '1042452822',
               '3221056763',
               '367472040',
               '2880955737',
               '774292992',
               '1611999631'
               ]
    APP_SECRET = [
                  
                  '59f42a032177e22cfb738067fd481855',
                  'ceb63e1afc177ad21d06e22317fa88c9',
                  '4acf19662aff8a9dd1f5e2941d1975c1',
                  '5a2d00b6face2762d92de04ee1e8d799',
                  '0a7a707442089290b6fdaff9842f2786',
                  '08811a2e2f6e0c2ae8ce8b63676b84a5',
                  '01ecee0a13785b5e0b394b60c0acebc6',
                  '72c202d5bc094ef57210909ecc290c66'
                  ]
    CALL_BACK = 'https://api.weibo.com/oauth2/default.html'
    
    isUsed = 2
    
    def __init__(self):
        
        # app 
        self.app_key = Sina.APP_KEY[Sina.isUsed]
        self.app_secert = Sina.APP_SECRET[Sina.isUsed]
        self.call_back = Sina.CALL_BACK
        
        Sina.isUsed = Sina.isUsed + 1
        if Sina.isUsed >= len(Sina.APP_KEY):
            Sina.isUsed = 0
            
        # client 
        self.client = ""
        
        
        self.weidu = ''
        self.jingdu = ''
        
        self.poiiddict = {}
        self.poiidCnt = 0
        
    def startAPIClient(self):
        self.client = weibo.APIClient(self.app_key, self.app_secert, self.call_back)
        # 獲取該應用(APP_KEY是唯一的)提供給使用者進行授權的url
        auth_url = self.client.get_authorize_url()
        # 打印出使用者進行授權的url,將該url拷貝到瀏覽器中,伺服器將會返回一個url,該url中包含一個code欄位(如圖1所示)
        print auth_url
        # 輸入該code值(如圖2所示)
        code = raw_input("input the retured code : ")
        # 通過該code獲取access_token,r是返回的授權結果,具體引數參考官方文件:
        # http://open.weibo.com/wiki/Oauth2/access_token
        r = self.client.request_access_token(code)
            # 將access_token和expire_in設定到client物件
        self.client.set_access_token(r.access_token, r.expires_in)
        return self.client
             
        
    def start(self, weidu , jingdu):
        self.weidu = weidu
        self.jingdu = jingdu
        
        poilst = PoiidList(self.client , self.weidu , self.jingdu)
        
        self.poiiddict , self.poiidCnt = poilst.getPoiid()
        
        userinfo = UsersInfo(self.poiiddict , self.client)
           
        userinfo.getinfo()
          
        
    def printINFO (self):
        print self.weidu
        print self.jingdu
        print self.poiidCnt
        
        
class UsersInfo(object):
    '''
    classdocs
    '''

    def __init__(self, poiiddict, Client):
        '''
        Constructor
        '''
        self.poiiddict = poiiddict
        self.client = Client
        
    def getinfo(self):
        
        for Poiid in self.poiiddict.keys():
            
            while True : 
                try :
                    tmp = self.client.place.pois.users.get(poiid=Poiid, count=50, page=1)
                    break
                except weibo.APIError : 
                    sn = Sina()
                    self.client = sn.startAPIClient()
                except urllib2.HTTPError:
                    pass
                 
            # # 計算這個poiid 的總人數
            try:
                poiid_User_cnt = tmp['total_number']
            
            except TypeError:
                continue
            
            filename = self.poiiddict[Poiid]
            print u"一共有%d個人在%s簽到" % (poiid_User_cnt, filename)
            
            # # 計算總頁數
            Cnt = poiid_User_cnt // 50
            
            if poiid_User_cnt % 50 != 0 :
                Cnt = Cnt + 1
            # # 建立檔案並輸出
            fw = codecs.open("/home/bitwater/workSpace/eclipseSpace/sinaCraw/SinaSDK/sina/" + filename + ".csv", "w", "utf-8",)
            
            fw.write(u"有%d個" % (poiid_User_cnt))
            
            fw.write(u"使用者名稱,使用者id,出發地, 性別,簽到時間\n")
            # # 獲取每一頁
            for i in range(1, Cnt + 1):
                print "第%d頁" % (i)
                
                while True : 
                    
                    try :
                        everinfo = self.client.place.pois.users.get(poiid=Poiid, count=50, page=i)
                        break
                    except weibo.APIError : 
                        sn = Sina()
                        self.client = sn.startAPIClient()
                    except urllib2.HTTPError:
                        pass 
#                         everinfo = self.client.place.pois.users.get(poiid=Poiid, count=50, page=i)
                    
                for user in everinfo['users']:
                    fw.write(user['name'] + " ,")
                    fw.write(str(user['id']))
                    fw.write(" ,")
                    fw.write(user['location'] + " ,")
                    fw.write(user['gender'] + " ,")
                    fw.write(user['checkin_at'] + '\n')
            fw.close()
        
if __name__ == '__main__':

    
    weidu = "+29.13"
    jingdu = "+110.47"
#     weidu = raw_input(u"輸入維度")
#     jingdu = raw_input(u"輸入經度")
    
    sina = Sina()
    sina.startAPIClient()
    
    sina.start(weidu, jingdu)
    

    
    
# -*- coding: utf-8 -*-

'''
Created on 2016年12月19日

@author: bitwater
'''
import weibo
import codecs
from pyasn1.compat.octets import null


class PoiidList(object):
    '''
    get poiid 
    '''
    def __init__(self, Client, weidu, jingdu):
        '''
        Constructor
        '''
        self.client = Client
        self.poiiddict = {}
        self.weidu = weidu
        self.jingdu = jingdu
        self.poiid_cnt = 0
        
        self.listlimit = 50
    def getPoiid(self):
        tmp = self.client.place.nearby.pois.get(lat=self.weidu , long=self.jingdu , count=50 , range=10000, sort=3)

        self.poiid_cnt = tmp['total_number'] 
        print "該位置一共有%d個Poiid" % (self.poiid_cnt) 
        
        st = 1 
        cnt = self.poiid_cnt // self.listlimit 
        print "%d" % (cnt)
        
        
        
        
        """
        ceshi
        """
#         st = 5
#         cnt = st + 4 
        
        
        fw = codecs.open("/home/bitwater/workSpace/eclipseSpace/sinaCraw/SinaSDK/sina/PoiidList.txt", "w", "utf-8")
        for i in range(st, cnt):
            try:
                print "%d" % (i)
                tmp = self.client.place.nearby.pois.get(lat=self.weidu , long=self.jingdu , count=self.listlimit , range=10000, sort=3, page=i)
                if tmp is null:
                    break 
                al = tmp['pois']
                # 輸出 Poiid 跟對應的 名稱 
                for one in al:
                    print one['poiid'] , one['title']
                    fw.write(one['poiid'])
                    fw.write("  ")
                    fw.write(one['title'])
                    fw.write('\n')
                    self.poiiddict[one['poiid']] = one['title']
            except TypeError: 
                continue
        
        fw.close()       
        return self.poiiddict , self.poiid_cnt