[英]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.