01-Twitter Streaming API的调用
郑昀 201006 隶属于《实时分析搜索引擎/02.数据获取》小节
修改历史:
1 2010年10月修正,因为Twitter要求必须走OAuth接口。
Twitter 提供了两种 Streaming 接口,让第三方可以省却轮询,由 Twitter 主动把合适的数据推送过来,近乎实时。
1、chirpstream api
接口地址是:http://chirpstream.twitter.com/2b/user.json [需FQ]
这个接口只是把你和你的好友以及各种与你有关的消息都推送过来。
参考此文《Tutorial: consuming Twitter's real-time stream API in Python 》,也可以从http://pastebin.com/U4m1Zsvs 这里复制此文源代码。
你需要维持一个 Socket 长连接。
你还需要通过 Twitter 的 OAuth 验证。
你将会得到一个 Twitter 用户登录后所应该看到的各种消息流。
我们检测单次数据包的最后是否以 \r\n 结尾:
if data.endswith("\r\n") and self.buffer.strip():
以此来判断检测一个完整的 JSON object 。
程序需要处理的几种常用消息:
- friends : 登陆用户都有哪些好友,即 my followings;这是一个id数组,每一个 id 代表一个用户,此 id 并非用户的 screenname ,而是 Twitter 用户的唯一数字标识。你可以通过持续积累 tweets 消息中的 user id ,从而获知自己的 friends id 数组中每一个 id 对应是谁。
- event 之 retweet : 其他用户使用官方格式的 retweet 转发的消息;
- event 之 favorite : 其他用户使用官方格式的 favorite 按钮收藏的消息;
- event 之 follow : 其他用户关注了本登陆用户;
- tweet : 普通的消息。从 in_reply_to_user_id 字段可获知是回复给谁的消息。
friends 消息数据示范如下:
{u'friends': [80831118, 750713, 1580781,]}
event 共有以下类型:
- follow
- direct_message
- retweet
- favorite
- unfavorite
- delete
event 之 消息数据示范如下:
{u'source': {u'id': 1490631, u'location': u'30.209214,120.198216',u'screen_name': u'Fenng'}, u'created_at': u'Sun Jun 20 08:46:09 +0000 2010', u'target': {u'id': 31347758, u'screen_name': u'minzhou',u'name': u'Min Zhou'u'following': True}, u'event': u'follow' }(已略去大量无关字段)即 Json 中用 u'event': u'follow' 来指明本消息是什么类型的 event 消息。
tweet 消息数据示范如下:
{u'text': u'@cnkang \u5176\u5b9e\u6211\u5bf9\u627e\u5927\u8d28\u6570\u66f4\u6709\u5174\u8da3\u2
026\u2026', u'created_at': u'Sun Jun 20 08:43:36 +0000 2010', u'coordinates': None, u'source': u'<a href="http://echofon.com/" rel="nofollow">Echofon</a>', u'in_reply_to_status_id': None, u'in_reply_to_screen_name': u'cnkang', u'in_reply_to
_user_id': 35457544, u'place': None, u'geo': None, u'id': 16604579153L, u'user': {u'id': 6132042, u'screen_name': u'delphij', u'following': None}}(已略去大量无关字段)这是一个 Reply 消息。一般 Twitter 客户端软件都是根据此消息体内的“in_reply_to_user_id ”字段判断被回复者的id 是不是自己的id,或者在不在自己的 friends id 数组里,如果都不是,就可以忽略此 Reply 消息。
2、streaming api
Twitter 的这个接口能够让第三方近乎实时地获取公开数据的各种子集:
『The Twitter Streaming API allows near-realtime access to various subsets of Twitter public statuses.』
接口地址:http://dev.twitter.com/pages/streaming_api ,需FQ。
2.1.权限问题
以 Streaming 方式连接 stream.twitter.com ,需要先通过 Twitter OAuth验证。
目前默认访问者只能使用 filter 这一个方法。
其他的 firehose 、retweet 、links 等方法则必须拥有访问权限,否则会得到如下提示:
Error 403 User not in required role
。
如果想申请特别权限,可以写信给 api@twitter.com ,说明原因。
2.2.判断 Json Object 结尾
由于是长连接,所以判断一个完整的 Json Object ,需要某个特殊标志。这还需要请求参数的配合。
Streaming API 的 filter 方法有一个输入参数:delimited。
它的含义『Indicates that statuses should be delimited in the stream. Statuses are represented by a length, in bytes, a newline, and the status text that is exactly length bytes. Note that "keep-alive" newlines may be inserted before each length.』
所以我们指定它的值是 newline ,这样 Json Object 之间就以 \r\n 作为分隔符。
文档上称 『 every object is returned on its own line, and ends with a carriage return.
Newline characters (\n) may occur in object elements (the text element of a status object, for example),
but carriage returns (\r) should not.』也就是说,\n 会出现在 Json Object 包体内,但 \r 则不会。
所以,我们检测单次数据包的最后是否以 \r\n 结尾:
if data.endswith("\r\n") and self.buffer.strip():
以此来判断检测 JSON object 的结尾。
2.3.Streaming API无法处理『Non-space delimited languages』
Twitter 的 John Kalucki 曾经这样回答:
We break the status text into tokens by whitespace and punctuation, then
apply the tokens to a hashmap of tracked terms. If the language doesn't have
whitespace, the only thing that will match is the entire Tweet.
即 Streaming API 目前还不能支持阿拉伯语、汉语、日语等『Non-space delimited languages』,原因是他们只能根据空格和标点把tweet打散成一个一个token。
http://apiwiki.twitter.com/User-Stream-Implementation-Suggestions 也有一句话提示:
『Non-space delimited languages are currently unsupported by track. For example: Arabic, Chinese, and Japanese language queries will not return results.』
2.4.track 参数的输入
先不理会他们能不能处理亚洲文字的追踪。
我们用
track = ["的","我","了","#duanzi","@rtmeme","@zhengyun"]
这么一个数组定义所要追踪的 keywords ,词与词是 Or(或) 的关系。注意,参考我的“玩聚网技术Wiki\01.数据抓取”之《06-HTTP请求中的编码问题》,必须对track里的中文字符的 UTF-8 编码字符串做转义:
trackKeywords = map(lambda s: unicode(s, 'gbk', 'ignore').encode('UTF-8', 'ignore'),track)
一旦一条新 tweet 发布,正文提及了 track 数组中的某一个词,这条消息就会被主动推送过来。它的 Json 格式与 chirpstream api 之 tweet 格式一样。
2.5.locations 参数的输入
filter 方法支持用发布者的地理位置过滤,比如 locations 参数为
[-74,40,-73,41]
就可以把从 New York 发布的 tweets 都推送过来。这也要求用户的 tweet 用 Geotagging API 发布,否则无法确定发布者的地理信息。默认用户设置中“Add a location to your tweets”这个选项是选中的。
-74,40的含义是,经度-74,维度40.
第一对经纬度应该是目标区域的SW(西南角)的位置信息。
-74,40和-73,41选中的区域叫做 bounding box ,这个区域很小,经度维度之间不能相差一度。如果区域过大,会得到如下提示:
Location track must be less than 1 degrees on a side 。
你选中的目标区域,它的经纬度信息可从:http://www.getlatlon.com/ 得到。
注:中国大陆用户很多都是从代理上的 Twitter ,所以它的 geo 信息可能是代理的。
2.6.Twitter Annotations的追踪
Twitter Streaming API将支持Twitter Annotations:你可以track一个注释类型,比如你可以近乎实时地得到所有标注了“movie”注释类型的 tweets ;你还可以track一个注释类型和值。
背景知识:什么是Twitter Annotations. 背景PPT:[slideshare]Twitter API Annotations .