天天看點

01-Twitter Streaming API的調用 | 02.資料擷取01-Twitter Streaming API的調用

修改曆史:

1 2010年10月修正,因為twitter要求必須走oauth接口。

這個接口隻是把你和你的好友以及各種與你有關的消息都推送過來。

你需要維持一個 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 消息。

twitter 的這個接口能夠讓第三方近乎實時地擷取公開資料的各種子集:

『the twitter streaming api allows near-realtime access to various subsets of twitter public statuses.』

以 streaming 方式連接配接 stream.twitter.com ,需要先通過 twitter oauth驗證。

目前預設通路者隻能使用 filter 這一個方法。

其他的 firehose 、retweet 、links 等方法則必須擁有通路權限,否則會得到如下提示:

error 403 user not in required role

由于是長連接配接,是以判斷一個完整的 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 結尾:

以此來判斷檢測 json object 的結尾。

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。

『non-space delimited languages are currently unsupported by track. for example: arabic, chinese, and japanese language queries will not return results.』

先不理會他們能不能處理亞洲文字的追蹤。

我們用

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 格式一樣。

filter 方法支援用釋出者的地理位置過濾,比如 locations 參數為

[-74,40,-73,41]

-74,40的含義是,經度-74,次元40.

第一對經緯度應該是目标區域的sw(西南角)的位置資訊。

-74,40和-73,41選中的區域叫做 bounding box  ,這個區域很小,經度次元之間不能相差一度。如果區域過大,會得到如下提示:

location track must be less than 1 degrees on a side 。

注:中國大陸使用者很多都是從代理上的 twitter ,是以它的 geo 資訊可能是代理的。