[英]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
附加到foo
, foo
和bar
实际上也引用相同的东西(因此更改一个会改变它们)。
如果您打算这样做,这是一个非常好的解决方案。 但是,如果您打算将推文与不同的听众分开,那可能会让您头疼不已。 我个人会这样构建我的类:
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_file
是self.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.