2016-01-22 19 views
5

Próbuję uzyskać wszystkie tweety (liczba całkowita liczba tweet) należą do hashtag. Moja funkcja jest tutaj, jak używać maxID i sinceID, aby uzyskać wszystkie tweety. Czym jest zamiast "liczyć"? Nie wiem.Jak uzyskać wszystkie tweety na Hashtag za pomocą LinqToTwitter

if (maxid != null) 
     { 
      var searchResponse = 
       await 
       (from search in ctx.Search 
       where search.Type == SearchType.Search && 
       search.Query == "#karne" && 
       search.Count == Convert.ToInt32(count) 
       select search) 
       .SingleOrDefaultAsync(); 

      maxid = Convert.ToString(searchResponse.SearchMetaData.MaxID); 

      foreach (var tweet in searchResponse.Statuses) 
      { 
       try 
       { 
        ResultSearch.Add(new KeyValuePair<String, String>(tweet.ID.ToString(), tweet.Text)); 
        tweetcount++; 
       } 
       catch {} 
      } 

      while (maxid != null && tweetcount < Convert.ToInt32(count)) 
      { 
       maxid = Convert.ToString(searchResponse.SearchMetaData.MaxID); 
       searchResponse = 
        await 
        (from search in ctx.Search 
        where search.Type == SearchType.Search && 
        search.Query == "#karne" && 
        search.Count == Convert.ToInt32(count) && 
        search.MaxID == Convert.ToUInt64(maxid) 
        select search) 
        .SingleOrDefaultAsync(); 
       foreach (var tweet in searchResponse.Statuses) 
       { 
        try 
        { 
         ResultSearch.Add(new KeyValuePair<String, String>(tweet.ID.ToString(), tweet.Text)); 
         tweetcount++; 
        } 
        catch { } 
       } 
      } 

     } 

Odpowiedz

9

Oto przykład. Pamiętaj, że MaxID jest dla bieżącej sesji i zapobiega ponownemu odczytaniu tweetów, które już przetworzyłeś w bieżącej sesji. SinceID to najstarszy tweet, jaki kiedykolwiek otrzymałeś dla tego wyszukiwanego hasła i pomaga uniknąć ponownego czytania tweetów, które już przetworzyłeś dla tego wyszukiwanego hasła podczas poprzednich sesji. Zasadniczo tworzysz okno, w którym MaxID jest najnowszym tweetem, aby uzyskać następny, a SinceID jest najstarszym tweetem, którego nie chcesz czytać. W pierwszej sesji dla danego wyszukiwanego hasła ustawisz SinceID na 1, ponieważ nie masz jeszcze najstarszego tweeta. Po zakończeniu sesji zapisz numer SinceID, aby przypadkowo nie przeczytać ponownie tweetów.

static async Task DoPagedSearchAsync(TwitterContext twitterCtx) 
    { 
     const int MaxSearchEntriesToReturn = 100; 

     string searchTerm = "twitter"; 

     // oldest id you already have for this search term 
     ulong sinceID = 1; 

     // used after the first query to track current session 
     ulong maxID; 

     var combinedSearchResults = new List<Status>(); 

     List<Status> searchResponse = 
      await 
      (from search in twitterCtx.Search 
      where search.Type == SearchType.Search && 
        search.Query == searchTerm && 
        search.Count == MaxSearchEntriesToReturn && 
        search.SinceID == sinceID 
      select search.Statuses) 
      .SingleOrDefaultAsync(); 

     combinedSearchResults.AddRange(searchResponse); 
     ulong previousMaxID = ulong.MaxValue; 
     do 
     { 
      // one less than the newest id you've just queried 
      maxID = searchResponse.Min(status => status.StatusID) - 1; 

      Debug.Assert(maxID < previousMaxID); 
      previousMaxID = maxID; 

      searchResponse = 
       await 
       (from search in twitterCtx.Search 
       where search.Type == SearchType.Search && 
         search.Query == searchTerm && 
         search.Count == MaxSearchEntriesToReturn && 
         search.MaxID == maxID && 
         search.SinceID == sinceID 
       select search.Statuses) 
       .SingleOrDefaultAsync(); 

      combinedSearchResults.AddRange(searchResponse); 
     } while (searchResponse.Any()); 

     combinedSearchResults.ForEach(tweet => 
      Console.WriteLine(
       "\n User: {0} ({1})\n Tweet: {2}", 
       tweet.User.ScreenNameResponse, 
       tweet.User.UserIDResponse, 
       tweet.Text)); 
    } 

Takie podejście wydaje się dużo kodu, ale naprawdę daje większą kontrolę nad wyszukiwaniem. na przykład możesz sprawdzać tweety i określać, ile razy należy wysyłać zapytania w oparciu o zawartość tweeta (np. CreatedAt). Możesz zawijać zapytanie w bloku try/catch, aby oglądać HTTP 429 po przekroczeniu limitu stawek lub gdy twitter ma problem, pozwalając Ci zapamiętać, gdzie jesteś i wznowić. Można również monitorować właściwości, aby sprawdzić, czy zbliżasz się i uniknąć wyjątku dla HTTP 429 z wyprzedzeniem. Każda inna technika ślepego czytania N-tek może zmusić Cię do marnowania limitu stawki i zmniejszenia skalowalności aplikacji.

  • Wskazówka: Pamiętaj, aby zapisać SinceID dla danego wyszukiwania wyrażenia, jeśli jesteś oszczędności tweets, aby powstrzymać się od ponownego czytanie tej samej Tweety następnym razem nie szukaj z tej szukanej.

Aby uzyskać więcej informacji na temat mechaniki tego, przeczytaj Working with Timelines w dokumentacji na Twitterze.

+0

Ten kod naprawdę nie działa. Przechodzi w nieskończoną pętlę, która EATS pamięci w urządzeniu. Osiągnięto ponad 1,3 GB pamięci RAM, a następnie awarie. Przez cały czas korzystał z internetu. Co ja robię źle? Użyłem EXACT tego samego kodu – Everyone

+0

@Everyone Szukane słowo "twitter" przywraca wiele tweetów. Możesz więc zmienić go na "LINQ to Twitter", który nie ma tak dużego ruchu. Możesz także sprawdzić datę utworzenia, aby upewnić się, że cofasz się tylko do przeszłości. Inną opcją jest ustawienie liczby tweetów, na których można się zatrzymać.Należy również zauważyć, że parametr SinceID ma wartość 1, co oznacza, że ​​wyszukiwanie będzie kontynuowane do momentu, w którym serwis Twitter przestanie generować wyniki lub osiągnie wartość parametru SinceID. Zapisywanie najnowszego identyfikatora odsprzedaży dla kolejnych połączeń pozwala uniknąć wysyłania duplikatów tweetów. Przeczytaj łącze Praca z podzespołami czasowymi, aby uzyskać więcej informacji. –

+0

Tak, zdałem sobie z tego sprawę. Nie zatrzymuje się, dopóki warunek nie nakazuje mu tego zrobić. Interesująca metoda. +1 :) – Everyone

0

Chciałem tylko powiedzieć, że z Tweetinvi byłoby tak proste, jak:

// If you want to handle RateLimits 
RateLimit.RateLimitTrackerOption = RateLimitTrackerOptions.TrackAndAwait; 

var tweets = Search.SearchTweets(new TweetSearchParameters("#karne") 
{ 
    MaximumNumberOfResults = 10000 
    MaxId = 243982 // If you want to start at a specific point 
}); 
+0

Czy naprawdę dostaje wszystkie tweety? –

+0

To może być w porządku w prostych scenariuszach. Jednak może to być marnotrawstwem, ponieważ można łatwo odczytać zduplikowane tweety podczas kolejnych wyszukiwań i może przekroczyć limity stawek dla dużej liczby tweetów, powodując wyjątki, które obniżają wydajność i skalowalność. –

+0

Czy naprawdę dostaje wszystkie tweety? TAK w pewnym momencie. Ale jak Joe dał ci rozwiązanie, cieszę się, że to rozwiązało. – Linvi

0

TweetInvi jest teraz jeszcze prostsze. Wszystko, co musisz zrobić, to:

var matchingTweets = Search.SearchTweets("#AutismAwareness"); 
+0

Wypracuj swoją odpowiedź – Billa