簡體   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