簡介
Twitter 現已成為社交網路中的佼佼者。Twitter 只允許使用者發布不多於 140 個字元的內容,誰能夠想到,這個過去毫不起眼的小網站如今卻價值十多億美元,擁有數百萬使用者,Twitter 平台上已構建了大量的應用程式,並且不斷有新的開發人員準備投入這一浪潮中。
本文並不打算介紹 Twitter(事實上,也沒有這個必要)。相反,本文將介紹如何訪問 Twitter 平台來構建出色的命令列應用程式。Twitter 支援各種程式設計語言,包括 C++、Java?、Perl、Ruby、PHP 和 Python。對於每種語言,都有大量的庫或包可以協助您完成大量工作。
本文將介紹如何使用 Ruby 來訪問 Twitter。您應該對 Ruby 有所瞭解,但是即使不具備這方面的知識,也很容易快速掌握 Ruby。
安裝 Twitter gem
一些 gem 可用於從 Ruby 訪問 Twitter(參見 參考資料,以獲得有關的更多資訊)。對於本文,我選擇使用 twitter,這是由 John Nunemaker 編寫的 Ruby 封裝器。安裝 gem 非常簡單:
bash$ gem install twitter
該命令用於在您的機器上安裝 Twitter 用戶端。如果您有一個定製的 gem 安裝資料夾,那麼首先需要從指令碼中調用 rubygems,然後調用 twitter。下面展示了具體過程:
require 'rubygems'require 'twitter'
第一個 Twitter 指令碼
現在,您已經準備好構建第一個應用程式,該應用程式用於檢測您所關注的人的位置。首先建立一個指令碼,它會擷取其他人的姓名,並告訴您他們的當前位置。清單 1 顯示了相關代碼。
清單 1. 跟蹤使用者位置
require 'rubygems'require 'twitter'def track ARGV.each do |name| puts name + " => " + Twitter.user("#{name}").location endend
track
這段代碼執行了哪些操作?如果您剛剛接觸 Ruby,則需要向您解釋一下,ARGV 是一個數組,它提供指令碼對命令列參數的訪問。Twitter.user API 返回有關您對其位置感興趣的人的資訊。調用以下指令碼可以獲得 Lady Gaga、Ashton Kutcher 和 Oprah Winfrey 的當前位置:
bash$ ./location_tracker.rb ladygaga aplusk Oprahladygaga => New York, NYaplusk => Los Angeles, CaliforniaOprah => Chicago, IL
在 Twitter 上實現使用者搜尋並瞭解認證情況
現在,讓我們搜尋 Twitter 上的一些現有使用者。如果可以猜出使用者的 Twitter ID,那麼可以使用以下命令列:
require 'rubygems'require 'twitter'puts "User exists" if Twitter.user?(ARGV[0])
不過,一般情況下無法猜出使用者的 ID。因此,需要提供搜尋使用者名稱的功能。這需要用以下代碼實現,該代碼將搜尋名稱與 Arpan 匹配的所有使用者:
require 'rubygems'require 'twitter'names = Twitter.user_search("Arpan")
但是這段代碼未能正常工作。清單 2 顯示的錯誤記錄檔告訴您問題出現在哪裡。
清單 2. 無法執行使用者搜尋
Twitter::Unauthorized: GET https://api.twitter.com/1/users/search.json?q=Arpan%20Sen: 401: Could not authenticate you. from D:/Ruby/lib/ruby/gems/1.8/gems/twitter-1.6.2/lib/faraday/response/raise_http_4xx.rb:12:in `on_complete' from D:/Ruby/lib/ruby/gems/1.8/gems/faraday-0.7.4/lib/faraday/response.rb:9:in `call' from D:/Ruby/lib/ruby/gems/1.8/gems/faraday-0.7.4/lib/faraday/response.rb:62:in `on_complete'
從這段代碼可以看出,您首先需要通過 Twitter 的認證,然後才能執行其他動作。這裡的認證不是要求您進行登入並輸入密碼;而是指對您的指令碼(在Twitter 中稱為 應用程式)進行認證。請牢記這一差異,然後訪問 http://dev.twitter.com/apps,並使用平常的帳號和密碼進行登入。Twitter 會要求您提供應用程式名稱、描述和應用程式的預留位置 (placeholder) 網站。提供這些資訊後,還必須提供以下四項內容實現指令碼認證:
- 使用者密匙(Consumer key)
- 使用者秘密令牌(Consumer secret token)
- 使用者 OAuth 密匙
- 使用者 OAuth 秘密令牌
現在,在 Ruby 代碼內部,您需要使用這些選項填充 Twitter.configure 對象。清單 3 顯示了相關代碼。
清單 3. 配置指令碼進行認證
Twitter.configure do |config| config.consumer_key = "mT4atgBEKvNrrpV8GQKYnQ" config.consumer_secret = "BiQX47FXa938sySCLMxQCTHiTHjuTTRDT3v6HJD6s" config.oauth_token = "22652054-Yj6O38BSwhwTx9jnsPafhSzGhXvcvNQ" config.oauth_token_secret = "o9JuQuGxEVF3QDzMGPUQS0gmZNRECFGq12jKs"end
注意,清單 3 中的條目是虛構的:您需要在指令碼中填充自己的內容。順利完成認證後,就可以搜尋名為 Arpan 的人(參見下面的 清單 4)。
清單 4. 在 Twitter 上搜尋使用者
require 'rubygems'require 'Twitter'Twitter.configure do |config| config.consumer_key = "mT4atgBEKvNrrpV8GQKYnQ" config.consumer_secret = "BiQX47FXa938sySCLMxQCTHiTHjuTTRDT3v6HJD6s" config.oauth_token = "22652054-Yj6O38BSwhwTx9jnsPafhSzGhXvcvNQ" config.oauth_token_secret = "o9JuQuGxEVF3QDzMGPUQS0gmZNRECFGq12jKs"endusers = Twitter.user_search(ARGV[0])users.each do |user| print "\n" + user.name + " => " print user.location unless user.location.nil?end
現在,將指令碼儲存為 search_for.rb,並在命令列中以 ./search_for.rb Arpan 形式呼叫指令碼後,您將獲得 清單 5 所示的使用者名稱稱。
清單 5. 清單 4 的代碼輸出
Arpan Jhaveri => New YorkArpan Boddishv =>Arpan Peter => Bangalore,IndiaArpan Podduturi => NYCArpan Kumar De => IIT KharagpurArpan Shrestha => Kathmandu, NepalArpan Divanjee => Mumbai,IndiaArpan Bajaj => Bay Area, CA
您可能期望獲得更多結果。Arpan 這個名字(印度姓名)並不少見,那麼為什麼搜尋結果這麼少?最後您會發現,user_search 使用了一個選擇性參數(一個 Ruby hash 表),您也可以指定可產生更多結果的選項。因此,可以稍微修改一下清單 5 的代碼,傳遞可選的 hash 參數(#)並預填充它的值。例如,如果希望在一個頁面中填充 15 項結果,那麼可以使用 清單 6 中的代碼。
清單 6. 在每個頁面顯示 15 項搜尋條目
require 'rubygems'require 'twitter'#.. authentication code hereusers = Twitter.user_search(ARGV[0], {:per_page => 15})#... same as Listing 10
是不是可以在每個頁面中顯示 100 項條目?不行,Twitter.user_search 允許每頁顯示的最多條目為 20。清單 7 顯示了如何在每個頁面中顯示 20 個條目。
清單 7. 每個頁面顯示 20 個條目
#... usual authentication stuffpagecount = 0while pagecount < 10 u = Twitter.user_search("#{ARGV[0]}", {:per_page => 20, :page => pagecount}) u.each do |user| print "\n" + user.name + " => " + user.screen_name print " => " + user.location unless user.location.nil? end unless u.size < 20 pagecount += 1end
現在看上去好多了。您現在可以根據偏好名和使用者的螢幕名稱搜尋使用者,下面讓我們做一些更有趣的事情。讓我們搜尋居住在紐約的、喜歡 Ruby 的名為 Nick 的人。您可以從 user_search 獲得姓名和位置,但是如何處理喜歡 Ruby 的搜尋要求?這引入了下一個需要學習的內容:建立定製搜尋用戶端。
使用 Twitter::Search 類
使用 Twitter::Search 類建立定製搜尋用戶端。清單 8 顯示了相關代碼。
清單 8. 學習使用 Twitter::Search 類
#... user authentication pagecount = 0while pagecount < 10 u = Twitter.user_search("#{ARGV[0]}", {:per_page => 20, :page => pagecount}) u.each do |w| if w.location == "New York" results = Twitter::Search.new.from(w.screen_name).containing("ruby").fetch puts w.screen_name if results.size > 10 end end unless u.size < 20 pagecount += 1end
這裡發生了什麼呢?代碼首先使用 Twitter::Search.new 建立了一個搜尋用戶端。接下來,要求搜尋用戶端從包含 ruby 的相應使用者那裡擷取所有 tweet。最後,代碼返回一組結果,如果在 tweet 中提到 Ruby 的次數超過十次,則將此人定義為喜歡 Ruby 的人。
讓我們嘗試為 hash 標記 #ruby 擷取一組 tweet。下面是具體實現:
#... user authentication coderesults = search.hashtag("ruby").fetchresults.each do |r| puts r.text + " from " + r.from_userend
不過,還可以實現更多內容。對於 ruby 之類的 hash 標記,您希望獲得數百個條目,不是嗎?對於這種情況,使用搜尋用戶端也會帶來便利,因為您可以從搜尋用戶端輕鬆地檢索下一個頁面。清單 9 的代碼顯示了有關 Ruby 的十頁 tweet。
清單 9. 顯示多個頁面
更多搜尋選項
搜尋用戶端可以讓您實現更出色的功能,比如使用特定語言或來自某個地方(比如德國)的 tweet。您甚至可以搜尋提到特定使用者的 tweet,或搜尋匹配特定條件的 tweet。例如,搜尋所有提到 Ruby 但沒有提到 Rails 的 tweet?嘗試下面的代碼:
search.containing("ruby").not_containing("rails").fetch
當然,您可以像下面這樣進行串聯:
search.containing("ruby").not_containing("rails").mentioning("username").from("place-id")
搜尋詞句非常直觀。例如,輸入以下代碼:
search.phrase("ruby on rails").fetch
現在,您已經掌握了入門要領!
速度限制
關於 Twitter,您需要瞭解一件重要的事情,即速度限制,Twitter 非常重視這個問題。速度限制意味著 Twitter 只允許您的指令碼每個小時執行有限次數的查詢。您可能已經發現,對於某些應用程式,您不需要進行顯式的認證,但是對於另外一些應用程式,認證則是必須的。對於不包含 OAuth 權杖的應用程式,當前的最大限制是每小時執行 150 個調用;對於帶有該標記的應用程式,允許每小時執行 350 個調用。有關 Twitter 速率限制的最新資訊,請查看 參考資源。要瞭解您的指令碼認證的當前限制,請添加以下代碼:
puts Twitter.rate_limit_status
下面是輸出結果:
<#Hashie::Mash hourly_limit=350 remaining_hits=350 reset_time="Sat Aug 13 21:48:59 +0000 2011" reset_time_in_seconds=1313272139>
如果您希望獲得更具體的結果,請用代碼查看下面的內容:
Twitter.rate_limit.status.remaining_hits
下面的輸出禁用了認證。注意,您已經用完了可用限制的 50%:
<#Hashie::Mash hourly_limit=150 remaining_hits=77 reset_time="Sat Aug 13 21:13:50 +0000 2011" reset_time_in_seconds=1313270030>
更新 Twitter 的狀態,重新發布 tweet 和其他內容
搜尋功能暫時告一段落。現在需要使用指令碼更新 tweet 的狀態。只需一行代碼即可(當然,您需要在指令碼中包含認證代碼):
#... authentication codeTwitter.update (ARGV [0])
將代碼儲存為 update.rb,並以 ruby update.rb "Hello World from Ruby Script" 的形式從命令列調用它。現在,您的 Twitter 頁面已經實現了更新!對話功能是 Twitter 的一個自然擴充,向另一個使用者發送訊息非常簡單:
#... authentication codeTwitter.direct_message_create("username", "Hi")
您可以選擇使用使用者的螢幕名或數字 ID 發送訊息。Twitter 的另一個有趣特性是可以快速查看最近發送的和最近接收到的 20 條訊息:
#... authentication codeTwitter.direct_messages_sent.each do | s | puts "Sent to: " + s.recipient_screen_name puts "Text: " + s.textend
我們有時候需要強調某些 tweet 的重要性,一個好方法就是重新發布 tweet。下面顯示了重新發布的最近 20 個 tweet:
#... authentication codeTwitter.retweets_of_me.each do |rt| print rt.text puts " retweet count = " + rt.retweet_count.to_send
當然,如果能知道是誰在重新發布 tweet 就更好了,但是無法從 retweets_of_me API 直接擷取該資訊。相反,您需要使用 retweeters_of API。注意,每個 tweet 都有一個唯一的 ID,而 retweeters_of 需要獲得這一 ID。清單 10 展示了相關代碼:
清單 10. 誰在向我重新發布 tweet
#... authentication codeTwitter.retweets_of_me.each do |rt| print rt.text print " retweeted by " Twitter.retweeters_of(rt.id).each do |user| puts user.screen_name endend
用 Twitter 實現有趣的功能
您可以利用自己的指令碼做許多有趣的事情。例如,假如您很關心當前 Twitter 中正在發生的事情,那麼您可以擷取前十個趨勢:
Twitter.trends.each do | trend | puts trend.nameend
twitter.com 只能報告前十個趨勢。參考 參考資源,獲得有關的更多資訊。通常,您可能只關心所在地的趨勢。只需要提供所在地的 where-on-earth ID (WOEID),Twitter 就可以提供這些資訊。下面我展示了如何獲得印度的當前趨勢:
Twitter.local_trends(12586534 ).each do | trend | puts trend #local_trends returns Stringend
獲得 Twitter 推薦的使用者也很容易。首先查看以下指令碼:
Twitter.suggestions("technology").users.each do | user | puts user.screen_nameend
我對這段代碼的輸出進行了仔細檢查。前十個結果意味著這段代碼可以正常工作。Twitter 提供了不同的使用者感興趣的類別,通過調用 Twitter.suggestions(只需將 Twitter.suggestions 放在指令碼裡)便可獲得此資訊。每個類別都有一個簡簡短名稱,在 Twitter 中稱為 slug,您需要將其傳遞給 Twitter.suggestions,然後便可獲得 Twitter 推薦的使用者。清單 11 展示了相關輸出。
清單 11. 技術類別中推薦的前幾名使用者
gruber
dannysullivan
AlecJRoss
timoreilly
Padmasree
tedtalks
OpenGov
twitter
BBCClick
woot
anildash
laughingsquid
digiphile
jennydeluxe
biz
ForbesTech
chadfowler
leolaporte
本文最後將介紹如何找到 Sachin Tendulkar(最棒的板球隊員)的最受歡迎的粉絲。首先,Sachin 的 ID 是 sachin_rt(在相關主題上,您可以使用 Twitter.user("sachin_rt").follower_count 查看其粉絲的數量,並使用 Twitter.user("sachin_rt").verified 確認他的狀態)。
現在,使用 Twitter.follower_ids("sachin_rt") 獲得 Sachin 粉絲的數量。預設情況下,您將獲得 5000 名使用者,這足夠支援您完成下面的工作。確保您已經閱讀 Twitter 文檔並參考了 Twitter 的 API resources for friends and followers,瞭解如何獲得完整的粉絲列表。下面是一個程式碼範例:
#... authenticate yourselfputs Twitter.follower_ids("sachin_rt").ids.size
最後,根據 follower_count 對這 5000 名使用者中的某些使用者進行排序:
#... authenticate yourselfputs Twitter.follower_ids("sachin_rt").ids[0..49].sort!{|a, b| \ Twitter.user(a).followers_count <=> \ Twitter.user(b).followers_count}.reverse.first.name
在 sort 之後,"!" 表示排序對所調用的內容修改了數組(並且沒有返回新的數組),花括弧({})中的代碼是比較功能。這解釋了使用 Ruby 的另一個原因:能夠在一行代碼中實現 20 行 C++ 程式碼完成的工作。
結束語
為 Twitter 編寫命令列指令碼非常有趣,並且可以使您洞悉 Twitter 尚未提供的功能。此外,無論是搜尋符合您的條件的特定使用者(從本地技術人員到領域中的主題專家),還是搜尋令人興奮的新 tweet,都可以很方便地通過命令列來實現。在結束本文之前,我需要給出最後兩條忠告:首先,Twitter 非常在意每小時的速率限制,因此最好將搜尋結果緩衝到您的代碼中。其次,隨時關注 Twitter 的 REST API 資源,其中列出了您的 Twitter 用戶端的所有 API。最重要的是,盡情享受 Twitter 的樂趣!