使用Python操作新浪微博
@马李奥之父
orangecnnps@
更新履历
文档地址:/doc/doclist.htm
本文简单介绍如何用Python操作新浪微博,如获取用户信息,发布一条新微博,评论微博,转发微博,删除微博等,并添加一些简单的实际应用的想法。
1.编程环境
Python2.7.3
Eclipse
PyDev2.6.0
wxPython2.8.12.1
编程环境配置不详述,本文中代码在该环境配置下测试通过。
2.新浪微博
了解OAuth验证
有关OAuth验证的细节,可以参考如下网址:
/
/hereweare/article/details/3968582
或者官方网站:
/
OAuth验证是为了将新浪微博接入目标网站时,目标网站不需要用户的用户名和密码即可申请获得其授权,对于本文介绍的程序,不需要其他用户的授权,但仍然需要遵循OAuth验证的步骤。
SDK
/sinaweibopy/
一个单py文件的sdk,包含一个封装的客户端类,包含一个发布微博的例子。
weibo1.py和自己创建的py文件放在同目录下。
/p/sinatpy/downloads/list
一个完整的sdk,下载sinatpy2.x-(-6-8).zip,解压后将weibopy文件夹拷贝到Python目录下的Lib/site-packages内。
本文综合了这两个sdk的内容,所以都要下载。
SDK文档
/wiki/API%E6%96%87%E6%A1%A3_V2
新浪的SDK文档详细介绍了微博操作的授权机制,API操作接口,地理位置服务接口和操作频率的限制。
3.新浪微博提供的相关接口
常用接口:
(1)、微博接口
获取最新的公共微博列表;
获取登录用户及关注用户的微博列表;
获取指定用户的微博列表;
发布微博;
删除微博;
转发微博;
……
(2)、评论接口
某条微博的评论列表;
登录用户发出的评论列表;
登录用户收到的评论列表;
评论一条微博;
评论一条评论;
删除一条评论;
获取@登陆用户的评论;
……
(3)、关系接口
获取登录用户的关注人列表;
获取登录用户的粉丝列表;
关注某用户;
取消关注某用户;
……
其他接口:
账号,收藏,话题,标签,注册,搜索,推荐,提醒,通知,位置服务,地理信息等接口。
4.开发者密钥
需要在新浪微博开发平台实名注册(需要上传证件照片),注意此注册和微博用户没有关系,是开发者的注册。注册后需要若干个工作日审核通过,通过以后可以创建一个应用,此应用附带有一对密钥。进行API操作需要这个密钥来通过验证。
5.相关代码
(1)、导入相关功能
#导入文件weibo1.py中的APIClient,OAuthToken类
fromweibo1 import APIClient, OAuthToken
#导入文件weibopy/auth.py,weibopy/api.py,weibopy/error.py中的相关类
from weibopy.authimport OAuthHandler
from weibopy.apiimport API
from weibopy.errorimport WeibopError
(2)、得到操作微博账户的APIClient对象实例,该函数内实现OAuth的三步骤验证,分别为client.get_request_token(),client.get_authorize_url(reqToken),client.get_access_token()
#通过输入用户名和密码,得到一个APIClient对象实例
#注意这里的用户名是注册邮箱,不是账号昵称
def GetWeiboClient(uname,passw):
#开发者密钥,需要在新浪微博开发平台实名注册后,新建一个应用方可得到一对密钥
APP_KEY = u'xxxxxxxxx'# app key
APP_SECRET = u'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'# appsecret
#实例化APIClient
client =APIClient(app_key=APP_KEY, app_secret=APP_SECRET)
#获取OAuth request token
reqToken = client.get_request_token()
#用户授权url
auth_url = client.get_authorize_url(reqToken)
post_data = urllib.urlencode({
"action":"submit",
"forcelogin":"",
"from":"",
"oauth_callback":"/oauth2/default.html",
"oauth_token": reqToken.oauth_token,
"passwd":passw,
"regCallback":"",
"ssoDoor":"",
"userId":uname,
"vdCheckflag":1,
"vsnval":""
})
mat = re.search(
r'&oauth_verifier=(.+)',
urllib2.urlopen(urllib2.Request(
"http://api./oauth/authorize",
post_data,
headers={
'User-Agent':'Mozilla/5.0 (Windows NT 6.1)',
'Referer': auth_url
})).url
)
if mat:
client = APIClient(
APP_KEY,
APP_SECRET,
OAuthToken(
reqToken.oauth_token,
reqToken.oauth_token_secret,
mat.group(1)
))
#返回APIClient
return APIClient(APP_KEY, APP_SECRET,client.get_access_token())
else:
print"Getweibo client error!"
raise Exception()
(3)、得到操作微博的API对象
Weibo = GetWeiboClient("name@","********")
#设定用户令牌密钥.
auth = OAuthHandler( Weibo.app_key, Weibo.app_secret, Weibo.api_url)
auth.setToken( Weibo.oauth_token, Weibo.oauth_token_secret)
#绑定用户验证信息.
apiWb = API(auth)
(4)、使用API对象操作微博
①获取登陆用户ID和用户昵称
user =apiWb.verify_credentials()
#用户ID
userid = user.id
#用户昵称.
username = user.screen_name.encode('utf-8')
②发布微博
#纯文本微博
apiWb.update_status("Hello Weibo!")
#带图片和文字的微博
apiWb.upload(filename ="D:/1.jpeg", status ="Hello Weibo with Pic!")
注意:不允许重复发内容相同的微博,当然也不允许发太快。下文中对微博接口的操作频率有介绍。
③获取用户微博详细信息
timeline= apiWb.user_timeline( screen_name ="name", count =1, page= -1 ); #返回值为微博列表。如果screen_name有输入值,则获取该昵称用户的微博,如果不输入screen_name参数,则获取登陆用户的微博,page为获取第几页的微博,count为每页显示几条微博,如果page为-1,则获取最近一页的微博。
for statusintimeline:
print status.id #微博id
print status.created_at #微博发布日期和时间
print status.user.name.encode('utf-8') #微博发布者昵称
print status.text.encode('utf-8') #微博正文
print status.source.encode('utf-8') #微博发布源,如XXX手机
coordinates = getattr( status.geo,"coordinates",None );
printcoordinates[0] #地理纬度,如31.123548
printcoordinates[1] #地理经度,如121.337265
refer = getattr( status,"retweeted_status",None );
print refer.user.name.encode('utf-8') #引用微博的发布者昵称
print refer.text.encode('utf-8') #引用微博的正文
print getattr( status,"original_pic",None ) #原图网址链接
printgetattr( status,"bmiddle_pic",None ) #中型图网址链接
printgetattr( status,"thumbnail_pic",None ) #缩略图网址链接
④获取公共用户的微博列表
timeline = apiWb.public_timeline()
for statusintimeline:
Analysis weibo list information
该函数返回最近其他用户发布的微博,默认每次调用返回的列表长度为20。这个列表是随机获取的,并不能获取一段时间内全部新浪微博用户发布的微博,而且如果连续取这个列表,相邻时间内取到的列表中含有重复内容。
⑤获取指定id的微博信息
Api.py中对于获取指定id的微博信息有错误,需要将代码
get_status =bind_api(
path ='/statuses/show.json',
payload_type ='status',
allowed_param = ['id'])
修改为:
get_status =bind_api(
path ='/statuses/show/'+'id'+'.json',
payload_type ='status',
allowed_param = ['id'])
调用方法:
status = apiWb.get_status(id = weiboid)
status信息获取见③
⑥获取登陆账号和关注用户的微博列表
timeline= apiWb.home_timeline( count = 1, page= -1 );
或者
timeline= apiWb.friends_timeline( count = 1, page = -1 );
for statusintimeline:
Analysis weibo list information
⑦删除一条微博
apiWb.destroy_status(status.id) #status.id为微博号
⑧转发微博
apiWb.repost(status.id,"Repost weibo content") #status.id为转发微博号,后边参数是转发时的信息
⑨评论一条微博
apiWb.comment(id = status.id, cid = comment.id, comment ="comment");
其中id为被评论的微博id,cid为评论的id,comment为评论内容。
⑩删除一条评论
ment_destroy(id = commentid)
commentid为被删除评论的id。
11获取某条微博的评论列表
commentslist = ments( id = status.id );
status.id为微博id。
另注意SDK的weibopy/models.py文件中有一个错误:
class Comments(Model):中的
elif k =='status':
status = Status.parse(api, v)
setattr(comments,'user', status)
应改为:
elif k =='status':
status = Status.parse(api, v)
setattr(comments, k,status)
关于评论的一些属性:
for commin commentslist:
print comm.id; #评论id
print comm.user.id; #评论者id
print comm.user.name.encode('utf-8'); #评论者昵称
print comm.text.encode('utf-8'); #评论内容
print comm.created_at; #评论日期时间
print comm.source.encode('utf-8'); #评论来源
status = getattr( comm,"status",None ); #得到被评论微博属性
print status.id; #被评论微博id
print status.user.id; #被评论微博作者id
reply = getattr( comm,"reply_comment",None ); #得到评论类型
if ( reply ): #如果评论的是评论
print reply.user['id']; #被评论者的id
print reply.user['name'].encode('utf-8'); #被评论者的昵称
print reply.text.encode('utf-8'); #被评论的评论内容
else: #如果评论的是微博
print status.user.id; #微博作者id
print status.user.name.encode('utf-8'); #微博作者名称
print status.text.encode('utf-8'); #原微博内容
12获取登陆用户的全部评论列表(发出的评论)
commentslist= ments_by_me();
评论的属性获取请参照上一条。
13获取登陆用户的全部被@信息列表
atlist = apiWb.mentions();
注意SDK的weibopy/utils.py中parse_datetime(str)如果str为空会出错,需要在代码中添加一下判断。
14获取关注列表
frlist = apiWb.friends(id = userid)
for frin frlist:
print fr.id #关注用户的id
print fr.screen_name.encode('utf-8') #关注用户的昵称
15获取粉丝列表
folist = apiWb.followers(id = userid)
for foin folist:
print fo.id #粉丝用户的id
print fo.screen_name.encode('utf-8') #粉丝用户的昵称
16关注某用户
apiWb.create_friendship(screen_name='昵称')
17取消关注某用户
apiWb.destroy_friendship(screen_name='昵称')
18其他功能
请参照SDK文档和相关SDK接口代码。
6.访问频率
为了均衡服务器的负载,微博接口限制用户每小时的API请求次数。
针对一个服务器IP的请求次数:
测试用户每小时1000次;
普通授权每小时10000次;
中级授权每小时20000次;
高级授权每小时30000次;
合作授权每小时40000次;
由于开发需要通过审核以后才能被授予普通授权,所以现在属于测试用户,每小时只能允许1000次请求。另外如果请求时间间隔太短,也会返回错误。
针对一个用户在使用一个应用的请求次数的限制:
测试授权:
总限制:单用户每应用每小时150次;
发微博:单用户每应用每小时30次;
发评论:单用户每应用每小时60次;
加关注:单用户每应用每小时60次,每天100次;
其他授权请参照新浪微博的开发SDK页面。
7.实际开发
一些简单的应用,如找到评论自己微博最多的几位好友,如分析某用户微博列表获取频率最高的一些关键字。
一些数据分析的应用,如分析某用户的微博使用习惯(原创多还是转发多,白天多还是晚上多,电脑发布多还是手机发布多,如果经常附带地理信息,可以分析一段时间内的方位变化等),分析某用户的微博内容以猜测他的职业和爱好,分析某用户的关系网,比如该用户关注的用户,关注用户关注的用户,该用户的粉丝,该用户粉丝的粉丝,得到自己感兴趣的用户列表等。
一些有趣的小应用,比如根据某些信息自动生成文字信息,或者根据用户互动自动生成图像信息,发送到用户的微博(比如指定文字“元芳,这件事情你怎么看?”、“大人,此事必有蹊跷。”,然后根据用户输入的图像,自动添加文字信息;相反,也可以针对某个指定图像,由不同用户输入不同的文字信息而生成新的图像)。
另外可以将微博作为一个远程信息通知和远程信息获取的服务器端和客户端,设计一些与图像处理相关的应用。
比如微博上流传较广的有饮水机开了,自动发送一条微博。或者主人不在家,可以用微博来喂狗,当然这些需要硬件配合,并需要考虑触发动作或者执行动作。
比如开发一款简单的防盗程序,用摄像头对家里的关键部位进行轨迹跟踪,如果家里有异常动静,从视频里提取一张有效图像发送到微博对主人进行提醒。
作为机器视觉的应用,如果给每台机器创建一个账号,每天把运行情况截屏,定时发送到微博,一定也是一件比较有意思的事情。
根据上述的接口,你也可以开发一个属于自己的微博桌面程序。
新浪微博的开发平台上有站内应用和移动平台应用的一些例子可以参考。可以根据微博附带的地理经纬度信息来创建一些位置帮助服务,比如推荐餐厅,找厕所,指路等。可以开发一些有趣的应用为用户生成好玩的文字或者图像信息作为微博发送。
另外还可以根据设定的规则,开发一个微博爬虫,获取海量的微博内容并搜索或者分析这些数据,以得到某些特定的信息或结论。但是这受到访问频率的一些限定。
8.微博喂狗的设计
硬件:
一台电脑;
一个USB摄像头;
一个IO输出装置;
一个光源;
一个电磁阀;
若干继电器;
一个装狗粮的盒子或者箱子,上边开大口输入狗粮,下边开小口输出狗粮,需要提前测试好输出口每秒钟流出狗粮的重量,按照狗狗每次的食量,算出输出时间。
软件:
一个新浪微博账号;
开发好的程序;
流程:
问题及改善点:
在各个步骤中,保存的关键图像是否有效图像是有一点难度的问题,比如狗来了一下便离开,或者来了没有吃把狗粮弄的到处都是,或者还没有开始采集之前狗已经在进食区域等待,狗吃完狗粮却一直不走开,在进食区域长时间停留等因素都会有一定影响,即如何判断狗已经在等待进食,如何判断狗已经进食完毕,单纯靠图像方法来解决并不牢靠。
微博在喂狗这个系统中起到的作用是命令接收方和结果发送方。在命令接收和结果发送两个功能中,其实只有命令接收是最重要的,系统只需要收到一个信号,控制打开狗粮输出通道,发出声音吸引狗来进食即可。如果狗没有来,系统并没有办法解决,而且结果是否发送,对喂狗的过程并不能有帮助,但是让主人实时得知狗狗是否进食成功对心理预期来说很重要。
为了支持微博实现这个功能,需要一直开着一台电脑,对于电力的消耗和硬件的投入都是一种浪费,如果不使用电脑,使用其他低成本硬件实现该功能,另可以用电话控制(出差不能上微博怎么办),并可以定时控制(最简单实用,定时开启,定时关闭),如果整套系统价格控制在几百块钱以内,预计会有一定的市场。而且微博作为一个大众平台,结果的转发和围观也能起到一定的广告效应。
9.微博提醒烧开水的设计
硬件:
一台电脑;
一个USB摄像头(电脑自带的也可以);
一个光源;
软件:
一个新浪微博账号;
一个开发好的程序;
流程:
问题和改善点:
如果有人来接水,阻挡了相机的视线,就会对算法造成干扰,所以需要考虑算法的鲁棒性。
指示灯还可能受到外界光照的影响,对算法造成影响,理想的方法是从饮水机内部指示灯的接点上并一根线出来,通过IO装置来捕捉烧水到烧开水的电压跳变。
用户的最终需求其实只是获取饮水机状态,所以最直观的方法是把摄像头变成网络摄像头,接水之前先获取摄像头视频,查看饮水机状态即可。用微博来周转一层其实只是为了找找乐子(如果使用了微博桌面等软件,被@会有提醒弹出的话再加一个提醒功能)。
最理想的方案是开发一个局域网内部程序,用传感器获取饮水机当前温度(因为一段时间后,水会变凉,进入重新加热状态),用传感器获取液面高度(及时发现水被喝完的状态),设计一个排队系统,当某用户打算去接水之前,先查看排队队列,如果队列人比较多,则决定等待(系统应分析当前的热水储存量和队列人数,判断热水是否会被接完,会在第几个人的时候被接完,假设每个人接水量基本一致),如果队列中人不多,则把自己加入接水队列,然后去接水。(防止温度和液面都合适,但是起身去接水以后,走到饮水机前面这段时间,热水被离的近的人接完了)。机器需要计算出刚刚被接走的水量,然后从排队系统中排除相应的排队人数。
如果有人插队怎么办?嗯,可以加一个人脸识别,如果在预期没有热水的前提下,某用户把自己加入了队列并且赶在其他排队用户之前跑到饮水机前接水,系统将会拒绝出水(顺便发布一条鄙视他的微博)。
10.看家功能设计
基本设计如上述两种设计,主要功能为如果家中无人,可以使用相机对准家中最薄弱的位置(门,某处窗户,或直接把相机对准某处贵重物品存放处,如果能放个一百块钱在醒目的地方,光线好的地方钓鱼最好),相机采集过程中如果有异物闯入视野,分析并保存有效图像,发送微博并@主人。考虑到电脑目标较大,可以使用手机来开发此类程序,需要注意的是手机需要隐蔽好,不要被人一起拿走,不过值得欣慰的是程序计算的速度一般比人快很多,应该能够在人拿走手机之前成功把微博发送出去了。收到微博赶紧打电话给保安或者能够帮忙的人,把闯入者堵住。如果没有来得及抓住,但愿发送的图像能够包含闯入者的有效信息(比如脸部特征,在程序中加入人脸探测的功能这个时候就凸显重要性),报案时用得到。微博在这个功能里起的作用其实是探测异物闯入和证据远程备份。
11.参考
参考文章:http://beauty./myStudy/Product/doc.-09-05.3305539365