【问题标题】:Stopping Tweepy stream after a duration parameter (# lines, seconds, #Tweets, etc)在持续时间参数(# 行、秒、#Tweets 等)之后停止 Tweepy 流
【发布时间】:2014-08-31 01:16:03
【问题描述】:

我正在使用 Tweepy 来捕获基于标签 #WorldCup 的流式推文,如下面的代码所示。它按预期工作。

class StdOutListener(StreamListener):
  ''' Handles data received from the stream. '''

  def on_status(self, status):
      # Prints the text of the tweet
      print('Tweet text: ' + status.text)

      # There are many options in the status object,
      # hashtags can be very easily accessed.
      for hashtag in status.entries['hashtags']:
          print(hashtag['text'])

      return true

    def on_error(self, status_code):
        print('Got an error with status code: ' + str(status_code))
        return True # To continue listening

    def on_timeout(self):
        print('Timeout...')
        return True # To continue listening

if __name__ == '__main__':
   listener = StdOutListener()
   auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
   auth.set_access_token(access_token, access_token_secret)

   stream = Stream(auth, listener)
   stream.filter(follow=[38744894], track=['#WorldCup'])

因为现在这是一个热门话题标签,所以搜索不会花费太长时间来捕获 Tweepy 让您在一次交易中获得的最大数量的推文。但是,如果我要在#StackOverflow 上进行搜索,它可能会慢得多,因此,我想要一种杀死流的方法。我可以在几个参数上执行此操作,例如在 100 条推文后停止、在 3 分钟后停止、在文本输出文件达到 150 行后等。我知道套接字超时时间不用于实现此目的。

我看过这个类似的问题:

Tweepy Streaming - Stop collecting tweets at x amount

但是,它似乎没有使用流 API。它收集的数据也很杂乱,而这个文本输出是干净的。

除了键盘中断之外,任何人都可以根据一些用户输入参数提出一种停止 Tweepy 的方法(在此方法中使用流时)?

谢谢

【问题讨论】:

  • 我对 Python 的 TwitterAPI 库有同样的问题

标签: python twitter streaming tweepy duration


【解决方案1】:

上述解决方案有助于通过主题标签获取推文,即使在定义 getTweetByHashtag 函数时出现小错误。你使用了 Listener.stopAt 而不是 Listener.stop_at=stop_at_number。

我已经稍微调整了代码,因此您可以轻松地在指定的秒数内终止代码。

定义了新函数 init 来帮助调整秒数和“on_data”,其中包含更多关于 on_status 函数的信息。

享受:

from tweepy import (Stream, OAuthHandler)
from tweepy.streaming import StreamListener

class Listener(StreamListener):

    tweet_counter = 0 # Static variable

    def login(self):
        CONSUMER_KEY =
        CONSUMER_SECRET =
        ACCESS_TOKEN =
        ACCESS_TOKEN_SECRET =

        auth = OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
        auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
        return auth

    def __init__(self, time_limit=8):
        self.start_time = time.time()
        self.limit = time_limit
        super(Listener, self).__init__()

    def on_data(self, data):
        Listener.tweet_counter += 1
        if (time.time() - self.start_time) < self.limit and Listener.tweet_counter < Listener.stop_at:
            print(str(Listener.tweet_counter)+data)
            return True
        else:
            print("Either Max number reached or time limit up at:"+ str(Listener.tweet_counter)+" outputs")
            self.saveFile.close()
            return False

    #def on_status(self, status):
        #Listener.tweet_counter += 1
        #print(str(Listener.tweet_counter) + '. Screen name = "%s" Tweet = "%s"'
              #%(status.author.screen_name, status.text.replace('\n', ' ')))

        #if Listener.tweet_counter < Listener.stop_at and (time.time() - self.start_time) < self.limit:
            #return True
        
        #else:
            #print('Max num reached or time elapsed= ' + str(Listener.tweet_counter))
            #return False

    def getTweetsByGPS(self, stop_at_number, latitude_start, longitude_start, latitude_finish, longitude_finish):
        try:
            Listener.stop_at = stop_at_number # Create static variable
            auth = self.login()
            streaming_api = Stream(auth, Listener(), timeout=60) # Socket timeout value
            streaming_api.filter(follow=None, locations=[latitude_start, longitude_start, latitude_finish, longitude_finish])
        except KeyboardInterrupt:
            print('Got keyboard interrupt')

    def getTweetsByHashtag(self, stop_at_number, hashtag):
        try:
            Listener.stop_at = stop_at_number
            auth = self.login()
            streaming_api = Stream(auth, Listener(), timeout=60)
            # Atlanta area.
            streaming_api.filter(track=[hashtag])
        except KeyboardInterrupt:
            print('Got keyboard interrupt')
   

    listener = Listener()
    #listener.getTweetsByGPS(20, -84.395198, 33.746876, -84.385585, 33.841601) # Atlanta area.
    listener.getTweetsByHashtag(1000,"hi")

您可以将 1000 值更改为您想要的最大推文,并将“hi”更改为您需要查找的关键字。在 init 函数下,将 8 time_limit 更改为您想要的值秒。因此,您可以根据需要使用它。

您可以设置有限的时间并将计数调整为一个非常高的值,或者设置所需的推文计数并给出更高的时间值,以便它可以达到计数。你的选择! Chukwu Gozie unu(上帝保佑!)

【讨论】:

    【解决方案2】:

    我解决了这个问题,所以我将成为那些回答自己问题的互联网英雄之一。

    这是通过对计数器和停止值使用静态 Python 变量来实现的(例如,在您抓取 20 条推文后停止)。目前这是一个地理位置搜索,但您可以使用 getTweetsByHashtag() 方法轻松地将其替换为主题标签搜索。

    #!/usr/bin/env python
    from tweepy import (Stream, OAuthHandler)
    from tweepy.streaming import StreamListener
    
    class Listener(StreamListener):
    
        tweet_counter = 0 # Static variable
    
        def login(self):
            CONSUMER_KEY =
            CONSUMER_SECRET =
            ACCESS_TOKEN =
            ACCESS_TOKEN_SECRET =
    
            auth = OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET)
            auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
            return auth
    
        def on_status(self, status):
            Listener.tweet_counter += 1
            print(str(Listener.tweet_counter) + '. Screen name = "%s" Tweet = "%s"'
                  %(status.author.screen_name, status.text.replace('\n', ' ')))
    
            if Listener.tweet_counter < Listener.stop_at:
                return True
            else:
                print('Max num reached = ' + str(Listener.tweet_counter))
                return False
    
        def getTweetsByGPS(self, stop_at_number, latitude_start, longitude_start, latitude_finish, longitude_finish):
            try:
                Listener.stop_at = stop_at_number # Create static variable
                auth = self.login()
                streaming_api = Stream(auth, Listener(), timeout=60) # Socket timeout value
                streaming_api.filter(follow=None, locations=[latitude_start, longitude_start, latitude_finish, longitude_finish])
            except KeyboardInterrupt:
                print('Got keyboard interrupt')
    
        def getTweetsByHashtag(self, stop_at_number, hashtag):
            try:
                Listener.stopAt = stop_at_number
                auth = self.login()
                streaming_api = Stream(auth, Listener(), timeout=60)
                # Atlanta area.
                streaming_api.filter(track=[hashtag])
            except KeyboardInterrupt:
                print('Got keyboard interrupt')
    
    listener = Listener()
    listener.getTweetsByGPS(20, -84.395198, 33.746876, -84.385585, 33.841601) # Atlanta area.
    

    【讨论】:

    • 超时停止怎么办?你没有在回答中提到这一点。我认为您对自己问题的回答不应该被接受:P
    • 如果你使用Twython,有一个很方便的方法叫disconnect
    • @hb20007:如果您认为您的解决方案更好,请发布新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-03
    相关资源
    最近更新 更多