新浪微博提醒脚本
2012-02-07无意中在微博上看到@乌云-漏洞报告平台 提起了一个关于“消息提醒未授权访问”的BUG。大致的看了一下网站上的截图,配合新浪微博的API 文档的介绍,估摸着弄了一下这个漏洞的实现脚本。其实,从实用的角度来看,这个BUG,基本上算不上严重(乌云的自评级才到3),也没有啥利用价值。又或者,像某位网友说的那样“由于这个接口流量过大而省去了认证环节”,而故意为之。
那,我为什么想着用脚本实现去利用这个漏洞呢?缘起放假前的一个idea。那段时间(包括现在)每天都在刷微博,浏览各种新闻网站,对网络产生了一种病态的依赖。想着,如果有一套提醒系统,在我关心的信息出现时,就自动推送给我,那该多好啊。而微博提醒自然可以通过其提供的API 来轻易实现。只不过当时玩API的时候没有注意别人的消息而已。
最近在看python 有关的书。目前,第二本已经看了一大半。寻思着练手的时候,正好可以借这个机会发挥一下。所以,这篇博客算是一个菜鸟看书笔记吧。如我微博所言,随便扫描了一圈,发现名人、艺人的微博信息普遍过载,而草根和技术流的微博都比较清静。下面是截图:这里是另外一张

python 脚本:
#coding: gbk
import urllib,sys
#appkey = 从sina API申请
class SINA(object):
'''简单的调用新浪微博OPEN API
DEMO:
s = SINA()
flag = s.init_api_object(appkey, u'陈坤')
if flag:
uid = s.get_uid()
'''
api_base_path = 'http://api.t.sina.com.cn/users/show.json?source='
def __init__(self):
self.sina = {}
@staticmethod
def build_api_url(appkey, user_screen_name):
'''生成新浪API URL
'''
if appkey and user_screen_name:
try:
return SINA.api_base_path + str(appkey) + '&screen_name=' \
+ urllib.quote(user_screen_name.decode(sys.stdin.encoding).encode('utf8'))
except :
return False
else:
return None
def init_api_object(self, appkey, user_screen_name):
''' 初始化API对象
appkey:从 [http://open.weibo.com/]申请
user_screen_name:就是微博界面上显示的名称
'''
try:
api = SINA.build_api_url(appkey, user_screen_name)
if api:
dic = urllib.urlopen(api).read()
dic = eval(str(dic).replace('false', 'False').replace('true', 'True').replace('null', 'None'))
if dic.has_key('error'):
return False
else:
self.sina = dic
else:
return False
except:
return False
else:
return True
def get_uid(self):
'''获取UID
'''
if self.sina:
return self.sina['id']
else:
return None
def get_description(self):
'''获取自我介绍
'''
if self.sina:
return self.sina['description']
else:
return None
def get_gender(self):
'''获取用户性别
'''
gender = {'m': 'male', 'f':'femail'}
if self.sina:
return gender[self.sina['gender']]
else:
return None
def get_followers_count(self):
'''获取粉丝数量
'''
if self.sina:
return self.sina['followers_count']
else:
return None
def get_friends_count(self):
'''获取关注数量
'''
if self.sina:
return self.sina['friends_count']
else:
return None
def get_statuses_count(self):
'''获取微博数量
'''
if self.sina:
return self.sina['statuses_count']
else:
return None
def get_favourites_count(self):
'''获取微博收藏数量
'''
if self.sina:
return self.sina['favourites_count']
else:
return None
def get_image_url(self):
'''获取微博头像
'''
if self.sina:
return self.sina['profile_image_url']
else:
return None
def get_domain(self):
'''获取微博地址
'''
if self.sina:
return self.sina['domain']
else:
return None
def get_location(self):
'''获取所在位置
'''
if self.sina:
return self.sina['location']
else:
return None
class SINA_NOTIFICATION(object):
'''SINA 微博消息API
DEMO:
s = SINA()
flag = s.init_api_object(APPKEY, u'陈坤')
if flag:
uid = s.get_uid()
sn = SINA_NOTIFICATION()
nf_flag = sn.init_notification(APPKEY, uid)
if nf_flag:
ns = sn.notifications()
for item in ns:
print "%s: %d"%(SINA_NOTIFICATION.dic[item],sn.get(item))
'''
api_base_path = 'http://api.t.sina.com.cn/remind/unread_count.json?source='
dic = {'attention':u'有新的粉丝',
'comment':u'有新的评论',
'msg':u'有新的私信',
'atme':u'有新提及我的微博',
'atcmt':u'有新提及我的评论',
'group':u'有新的微群消息',
'notice':u'有新通知',
'invite':u'有新的邀请',
'badge':u'有新的徽章',
'photo':u'有新的相册消息'}
def __init__(self):
self.nf = {}
@staticmethod
def build_api_url(appkey, uid):
'''生成API URL
'''
if appkey and uid:
try:
return SINA_NOTIFICATION.api_base_path + str(appkey) + '&user_id=' + str(uid)
except:
return False
else:
return False
def init_notification(self, appkey, uid):
'''初始化提醒对象
'''
try:
api = SINA_NOTIFICATION.build_api_url(appkey, uid)
if api:
dic = urllib.urlopen(api).read()
import os
self.nf = eval(dic.replace('\r\n', os.linesep))#Linux support
else:
return False
except:
return False
else:
return True
def notifications(self):
'''呈现消息
'''
n_list = []
if self.nf:
for item in self.nf:
if item == 'feed':
continue
if self.nf[item] > 0:
n_list.append(item)
return n_list
else:
return None
def has_notification(self):
'''是否有新的微博消息
'''
if self.nf:
cnt = 0
for item in self.nf:
if item == 'feed':
continue
cnt += self.nf[item]
if cnt > 0:
return True
else:
return False
def get_atme(self):
'''新提及我的微博数
'''
if self.nf:
return self.nf['atme']
else:
return None
def get_private_message(self):
'''新私信数
'''
if self.nf:
return self.nf['msg']
else:
return None
def get_comment(self):
'''新评论数
'''
if self.nf:
return self.nf['comment']
else:
return None
def get_atcmt(self):
'''@新提及我的评论数
'''
if self.nf:
return self.nf['atcmt']
else:
return None
def get_group(self):
'''微群消息未读数
'''
if self.nf:
return self.nf['group']
else:
return None
def get_photo(self):
'''相册消息未读数
'''
if self.nf:
return self.nf['photo']
else:
return None
def get_invite(self):
'''新邀请未读数
'''
if self.nf:
return self.nf['invite']
else:
return None
def get_badge(self):
'''新勋章数
'''
if self.nf:
return self.nf['badge']
else:
return None
def get_notice(self):
'''新通知未读数
'''
if self.nf:
return self.nf['notice']
else:
return None
def get_attention(self):
'''新粉丝数
'''
if self.nf:
return self.nf['attention']
else:
return None
def get(self, lable):
'''
'''
if lable not in ("attention","comment","msg","atme","atcmt","group","notice","invite","badge","photo"):
return None
if self.nf:
return self.nf[lable]
else:
return None
if __name__ == '__main__':
name = raw_input('请输入需要查询的昵称:')
s = SINA()
flag = s.init_api_object(appkey, name)
if flag:
uid = s.get_uid()
sn = SINA_NOTIFICATION()
nf_flag = sn.init_notification(appkey, uid)
if nf_flag:
if sn.has_notification():
ns = sn.notifications()
for item in ns:
print "%s: %d"%(SINA_NOTIFICATION.dic[item],sn.get(item))
else:
print '暂时还没有新的微博提醒'
else:
print 'something is error'.title()
else:
print ('没有找到与%s匹配的信息!'%name).title()
就在写博客的时候,我忽然想到可以把这个接口的数据进行稍微的梳理。比如找出名人堂里影响力排行榜前50的大V们,谁获得的@最多,谁私信最多,谁新增的粉丝最多,谁收到的评论最多…等等。于是停下了博客的更新,顺手写下了后面的这个脚本。虽然,拿到的数据也没有什么商业价值,但起码,对于一个刚刚熟悉脚本的人来说,算是玩尽兴了。ok, 上代码:
#coding: gbk
from sina import SINA, SINA_NOTIFICATION
#appkey = 才sina API申请
person_list = ['文章同學', '蔡康永', '陈坤', '吴奇隆', '何炅', '杨幂',
'任志强', '羅志祥','刘忻', '潘石屹', '陆琪', '宋丹丹',
'方舟子','魏晨','张杰','韩庚', '姚晨', '李开复', '韩志国',
'薛蛮子', '王力宏','马伊琍','汪东城', '周笔畅', '周立波',
'舒淇', '陈翔橙', '慕容雪村', '阿信', '宁财神', '范范范瑋琪',
'乐嘉', '企业家智库', '夢想家林志穎', '郭敬明', '炎亞綸','edc陳冠希',
'张小娴', '张泉灵', '小霜', '小P老师', '谢娜', '高考直通车', '罗玉凤',
'黑人建州', '牛尔', '鍾欣桐', '杜海涛Hito', '加措活佛-慈爱基金', '总裁语录'
]
def name_to_id(name, appkey):
s = SINA()
flag = s.init_api_object(appkey, name)
if flag:
return s.get_uid()
import cPickle
def save_id():
person_id = {}
try:
for item in person_list:
person_id[item] = name_to_id(item, appkey)
if len(person_id) == 50:
pfile = open('person_id.dat','wb')
cPickle.dump(person_id, pfile, protocol=0)
pfile.close()
else:
return False
except:
return False
else:
return True
def save_dic():
person_dic = {}
try:
pfile = open('person_id.dat','rb')
ids = cPickle.load(pfile)
pfile.close()
for item in person_list:
uid = ids[item]
sn = SINA_NOTIFICATION()
nf_flag = sn.init_notification(appkey, uid)
if nf_flag:
person_dic[item] = sn.nf
if len(person_dic) == 50:
dic_file = open('person_dic.dat', 'wb')
cPickle.dump(person_dic, dic_file, protocol=0)
else:
return False
except:
return False
else:
return True
def get_top_atme():
dic_file = open('person_dic.dat', 'rb')
dic = cPickle.load(dic_file)
dic_file.close()
atme_dic = {}
for item in person_list:
atme_dic[item] = dic[item]['atme']
s_list = sorted(atme_dic.items(), lambda x, y: cmp(x[1],y[1]), reverse = True)
return s_list[0][0], s_list[1][0], s_list[2][0]
def get_top_cmt():
dic_file = open('person_dic.dat', 'rb')
dic = cPickle.load(dic_file)
dic_file.close()
cmt_dic = {}
for item in person_list:
cmt_dic[item] = dic[item]['comment']
s_list = sorted(cmt_dic.items(), lambda x, y: cmp(x[1],y[1]), reverse = True)
return s_list[0][0], s_list[1][0], s_list[2][0]
def get_top_msg():
dic_file = open('person_dic.dat', 'rb')
dic = cPickle.load(dic_file)
dic_file.close()
cmt_dic = {}
for item in person_list:
cmt_dic[item] = dic[item]['msg']
s_list = sorted(cmt_dic.items(), lambda x, y: cmp(x[1],y[1]), reverse = True)
return s_list[0][0], s_list[1][0], s_list[2][0]
def get_top_new_followers():
dic_file = open('person_dic.dat', 'rb')
dic = cPickle.load(dic_file)
dic_file.close()
cmt_dic = {}
for item in person_list:
cmt_dic[item] = dic[item]['attention']
s_list = sorted(cmt_dic.items(), lambda x, y: cmp(x[1],y[1]), reverse = True)
return s_list[0][0], s_list[1][0], s_list[2][0]
import time
if __name__ == '__main__':
print '现在时刻:',time.ctime()
if save_id():
if save_dic():
func_list = [get_top_atme, get_top_cmt, get_top_msg, get_top_new_followers]
func_name = {get_top_atme: '@', get_top_cmt: '评论',
get_top_msg: '私信', get_top_new_followers: '新粉丝'
}
for item in func_list:
print '此刻, 获得最多%s的人是:'%func_name[item]
for it in item():
print '\t',it,'\t'
print '*'*40
print '处理完成:',time.ctime()
脚本的输出结果:
现在时刻: Wed Feb 08 00:15:36 2012
此刻, 获得最多@的人是:
方舟子
张小娴
edc陳冠希
****************************************
此刻, 获得最多评论的人是:
谢娜
刘忻
张杰
****************************************
此刻, 获得最多私信的人是:
薛蛮子
慕容雪村
阿信
****************************************
此刻, 获得最多新粉丝的人是:
方舟子
张杰
陈坤
****************************************
处理完成: Wed Feb 08 00:17:25 2012
参考资料:
分类:我的程序、网络应用 | 标签: BUG、python、微博 |