繁体   English   中英

如何通过tweepy保存json中的流媒体推文?

[英]How do I save streaming tweets in json via tweepy?

我通过在线课程学习了几个月的Python,并希望通过一个真实的迷你项目来进一步学习。

对于这个项目,我想从twitter流API收集推文并以json格式存储它们(虽然你可以选择保存关键信息,如status.text,status.id,我被告知最好的方法这样做是为了保存所有数据并在之后进行处理。 但是,通过添加on_data(),代码就不再起作用了。 有人能帮忙吗? 我也对有关存储/处理推文的最佳方式的建议持开放态度! 我的最终目标是能够根据人口统计变量(例如,国家/地区,用户资料年龄等)以及特定品牌(例如,Apple,HTC,Samsung)的情绪来跟踪推文。

此外,我还想尝试按位置和关键字过滤推文。 我已经改编了如何将位置过滤器分别添加到tweepy模块中的代码。 但是,虽然它在有少量关键字时有效,但在关键字数量增加时会停止。 我认为我的代码效率低下。 有没有更好的方法呢?

### code to save tweets in json###
import sys
import tweepy
import json

consumer_key=" "
consumer_secret=" "
access_key = " "
access_secret = " "

auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth)
file = open('today.txt', 'a')

class CustomStreamListener(tweepy.StreamListener):
    def on_status(self, status):
        print status.text

    def on_data(self, data):
        json_data = json.loads(data)
        file.write(str(json_data))

    def on_error(self, status_code):
        print >> sys.stderr, 'Encountered error with status code:', status_code
        return True # Don't kill the stream

    def on_timeout(self):
        print >> sys.stderr, 'Timeout...'
        return True # Don't kill the stream

sapi = tweepy.streaming.Stream(auth, CustomStreamListener())
sapi.filter(track=['twitter'])

我发现了一种将推文保存到json文件的方法。 很高兴听到它如何改进!

# initialize blank list to contain tweets
tweets = []
# file name that you want to open is the second argument
save_file = open('9may.json', 'a')

class CustomStreamListener(tweepy.StreamListener):
    def __init__(self, api):
        self.api = api
        super(tweepy.StreamListener, self).__init__()

        self.save_file = tweets

    def on_data(self, tweet):
        self.save_file.append(json.loads(tweet))
        print tweet
        save_file.write(str(tweet))

在重新阅读你的原始问题时,我意识到你提出了许多较小的问题。 我会尝试在这里回答大部分问题,但有些人可能真的要问一个单独的问题。

  • 为什么它会因添加 on_data on_data

没有看到实际的错误,很难说。 它实际上对我不起作用,直到我重新生成我的消费者/访问密钥,我试试。

我可能做的一些事情与你的答案不同。

tweets是一个全球列表。 这意味着如果您有多个StreamListeners (即在多个线程中),则任何流侦听器收集的每条推文都将添加到此列表中。 这是因为Python中的列表引用了内存中的位置 - 如果这令人困惑,这里是我的意思的基本示例:

>>> bar = []
>>> foo = bar
>>> foo.append(7)
>>> print bar
[7]

请注意,即使您认为将foo附加到foofoobar实际上也引用相同的东西(因此更改一个会改变它们)。

如果您打算这样做,这是一个非常好的解决方案。 但是,如果您打算将推文与不同的听众分开,那可能会让您头疼不已。 我个人会这样构建我的类:

class CustomStreamListener(tweepy.StreamListener):
    def __init__(self, api):
        self.api = api
        super(tweepy.StreamListener, self).__init__()

        self.list_of_tweets = []

这会将推文列表更改为仅在您的类的范围内。 此外,我认为将属性名称从self.save_file更改为self.save_fileself.list_of_tweets因为您还将要添加推文的文件命名为save_file 虽然这不会严格地导致错误,但是对于我而言, self.save_file是一个列表而save_file是一个文件,这让我感到困惑。 它可以帮助您和其他任何读取您的代码的人找出一切都在做什么。 更多关于变量命名。

在我的评论中,我提到你不应该使用file作为变量名。 file是一个Python内置函数,用于构造file类型的新对象。 你可以在技术上覆盖它,但这样做是一个非常糟糕的主意。 有关更多内置函数,请参阅Python文档

  • 如何过滤多个关键字的结果?

在这种类型的搜索中,所有关键字都是“ OR ”, 来源

sapi.filter(track=['twitter', 'python', 'tweepy'])

这意味着这将获得包含'twitter','python'或'tweepy'的推文。 如果您想要联合( AND )所有术语,则必须通过检查要搜索的所有术语列表的推文进行后处理。

  • 如何根据位置和关键字过滤结果?

我实际上刚刚意识到你确实问过这个问题,正如我将要提出的那样。 正则表达式后处理解决方案是实现此目的的好方法。 你也可以尝试按位置关键字进行过滤,如下所示:

sapi.filter(locations=[103.60998,1.25752,104.03295,1.44973], track=['twitter'])
  • 存储/处理推文的最佳方式是什么?

这取决于你将收集多少。 我是数据库的粉丝,特别是如果你打算在很多推文上做一个情绪分析。 收集数据时,您应该收集所需的内容。 这意味着,当您将结果保存到数据库/ on_data方法中的任何位置时,您应该从JSON中提取重要部分而不保存任何其他内容。 例如,如果您想看品牌,国家和时间,只需要考虑这三件事; 不要保存推文的整个JSON转储,因为它只会占用不必要的空间。

我只是将原始JSON插入数据库。 它似乎有点丑陋和hacky但它​​确实有效。 一个值得注意的问题是推文的创建日期存储为字符串。 如何通过PyMongo比较存储在MongoDB中的Twitter数据的日期? 提供了一种解决方法(我在代码中插入注释以指示执行该任务的位置)

# ...

client = pymongo.MongoClient()
db = client.twitter_db
twitter_collection = db.tweets

# ...

class CustomStreamListener(tweepy.StreamListener):
    # ...
    def on_status(self, status):
            try:
                twitter_json = status._json
                # TODO: Transform created_at to Date objects before insertion
                tweet_id = twitter_collection.insert(twitter_json)
            except:
                # Catch any unicode errors while printing to console
                # and just ignore them to avoid breaking application.
                pass
    # ...

stream = tweepy.Stream(auth, CustomStreamListener(), timeout=None, compression=True)
stream.sample()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM