2012-11-15 119 views
2

我正在嘗試構建一個服務,在Twitter上以不斷監視爲基礎爲多個用戶執行關鍵字搜索。似乎有5種不同的方式來實現這一點 - 所有這些都有自己的缺點。我瀏覽了Twitter和twitter4j文檔,找不到其他方法。如何搜索關鍵字的twitter

  1. 使用Twitter REST API執行搜索(https://dev.twitter.com/docs/api/1/get/search)。這個API是結果限制的:請求太多,你會受到限制。我必須跟蹤讀取的最後一條推文,以免重複結果。需要一個計時器來輪詢流。如果有多個搜索條件,則進行多個呼叫很簡單。

  2. 搜索公共碼流方法(https://dev.twitter.com/docs/streaming-apis/streams/public)。雖然這對於持續搜索很有用,但Twitter只允許每個帳戶建立一個連接,並且限制了可以傳遞給Twitter的條款數量。絕對不可能用於我的用例

  3. 嘗試使用用戶流進行過濾。我這樣做,但發現很難快速確定推文是來自搜索還是用戶流。此外,Twitter表示,他們將限制每個IP地址的用戶流數量,因此這種方法無法擴展。 (Twitter一直在談論一些名爲SiteStreams,但它是一個非常有限的測試版,沒有任何文檔,所以這是我不能考慮的)。

  4. 轉到從Twitter(例如Datasift)購買整個消防隊的第三方,並在那裏搜索Twitter流。這會變得很貴 - 基本計劃每月3千美元。尋找一個單詞24/7費用〜$ 45 /月)

我對社區的問題是「我用盡了所有的可能性」?如果是的話,那麼在我看來#1 - 使用帶有定時器的REST API並且最後找到的跟蹤是正確的方法。有人不同意嗎?如果是這樣,你能指點我的文檔(或庫),這將幫助我解決這個問題。

感謝所有

+0

對不起。添加了grails標籤,我想將twitter4j和grails代碼放在問題中。但是沒有必要。 –

回答

0

來自Twitter的回覆是使用#4 - 從供應商(如Datasift)購買訪問權。

0

如何頻繁地你想搜索Twitter,什麼是可能的搜索量(每用戶即有多少用戶,多少關鍵字)?

你是否也考慮過刮眉刀?即讓瀏覽器在與搜索結果保持同步的服務器上運行,併爲該瀏覽器開發一個簡單的插件,用於捕獲數據並將其發佈到數據庫/將其發送到某處進行處理?

+0

我想盡可能接近實時地搜索Twitter。這是用戶流的吸引力之一。搜索量在用戶方面將會很高;最好是幾千(分佈在水平縮放的AWS服務上)。我會極其嚴格地限制關鍵字,但即使要追蹤的關鍵字僅限於每個用戶一個關鍵字,我仍然會針對公共流中的400關鍵字限制運行。 –

+0

我沒有想過做瀏覽器刮板。這似乎有點複雜,可能會違反Twitter API限制的精神(冒着被Twitter列入黑名單的風險)。 –

4

我把一個很好的JS小提琴放在一起,它應該回答你處理Twitter API時的所有問題。該Web應用抓取熱門地區,並允許您深入探究趨勢主題,然後查看其中的推文。

我還包括一個標準的Twitter搜索提交框,所以以一種奇怪的方式,這是一個準系統Tweetdeck客戶端,供您檢查。另外,爲了推動新的Jquery庫的適應性,我使用了1.91新的live.bind click事件語法的實用工具。

享受

http://jsfiddle.net/jdrefahl/5M3Gn/

function searchTwitter(query) { 
$.ajax({ 
    url: 'http://search.twitter.com/search.json?' + jQuery.param(query), 
    dataType: 'jsonp', 
    success: function (data) { 
     var tweets = $('#tweets'); 
     tweets.html(''); 
     for (res in data['results']) { 
      tweets.append('<div>' + data['results'][res]['from_user'] + ' wrote: <p>' + data['results'][res]['text'] + '</p></div><br />'); 
     } 
    } 
}); 
} 

$(document).ready(function() { 

function getTrendsByID(id) { 
    $.ajax({ 
     url: 'http://api.twitter.com/1/trends/' + id + '.json', 
     dataType: 'jsonp', 
     success: function (data) { 
      $.each(data[0].trends, function (i) { 
      }); 
     } 
    }); 
}; 

function getLocales() { 
    $.ajax({ 
     url: 'https://api.twitter.com/1/trends/available.json', 
     dataType: 'jsonp', 
     success: function (data) { 
      var locales = $('ul#locales'); 
      locales.html(''); 
      $.each(data, function (i) { 
       localeID[i] = data[i].woeid; 
       $('ul#locales').append('<li>' + data[i].name + '</li>'); 
      }); 
     } 
    }); 

}; 

function getTrends(id) { 
    $.ajax({ 
     url: 'https://api.twitter.com/1/trends/' + id + '.json', 
     dataType: 'jsonp', 
     success: function (data) { 
      var trends = $('ul#currentTrends'); 
      trends.html(''); 
      $.each(data[0].trends, function (i) { 
       $('ul#currentTrends').append('<li>' + data[0].trends[i].name + '</li>'); 
      }); 
     } 
    }); 
}; 

// Event Handlers 
$(document).on("click", "#locales li", function() { 
    var $this = $(this); 
    var localesHdr = $('#currentTrendsCont h3'); 
    var tweets = $('#tweets'); 
    var trendsHdr = $('#tweetsCont h3'); 
    trendsHdr.html(''); 
    tweets.html(''); 
    localesHdr.html(''); 
    $('#currentTrendsCont h3').html($this.text()); 
    getTrends(localeID[$this.index()]); 
}); 

$(document).on("click", "#currentTrends li", function() { 
    var $this = $(this); 
    var trendsHdr = $('#tweetsCont h3'); 
    trendsHdr.html(''); 
    $('#tweetsCont h3').html($this.text()); 
    var params = { 
     q: $this.text(), 
     rpp: 10 
    }; 
    searchTwitter(params); 
}); 

$('#submit').click(function() { 
    var trendsHdr = $('#tweetsCont h3'); 
    var trends = $('#currentTrends'); 
    var local = $('#currentTrendsCont h3'); 
    local.html(''); 
    trendsHdr.html(''); 
    trends.html(''); 
    $('#tweetsCont h3').html('search query: '+$('#query').val()); 
    var params = { 
     q: $('#query').val(), 
     rpp: 10 
    }; 
    searchTwitter(params); 
}); 

// Globals 
var localeID = new Array(); 

// Init! 
getLocales(); 

});