Как я могу транслировать твиты несколько раз и анализировать результаты офлайн? - PullRequest
0 голосов
/ 11 июля 2020

Я транслирую твиты, которые будут использоваться для анализа настроений.

Сначала я подумал о потоковой передаче и анализе в реальном времени. Я следовал инструкциям и смог кое-что достичь ... (Я пока не очень хорошо в этом разбираюсь).

Все работало нормально, но проблема в том, что я обнаружил, что Twitter не возвращает все твиты, которые я указал, используя параметр count , и мне нужно проанализировать большое количество твитов. Поэтому я решил транслировать твиты с использованием max_id в первый раз и сохранять данные в кабине; после запуска соберите его последним и используйте его как max_id во второй раз ... Я намерен делать это, постоянно меняя имя файла csv каждый раз, когда я запускаю программу, а затем объединяю все файлы CSV и передавая его моей функции sentiment_analyzer ...

У вас всегда возникают проблемы, когда я пытаюсь проанализировать это в автономном режиме ... Из приведенного ниже кода 'all_tweets.csv' представляют все твиты, которые я хочу использовать для анализа но я всегда получаю KeyError: 'tweets' , когда запускаю его ...

Я не слишком опытен в этом, пожалуйста, кто-нибудь может мне помочь? Я застрял на несколько дней.

Заранее спасибо, ниже мой код

from tweepy.streaming import StreamListener

from textblob import TextBlob
 
import credentials_from_twitter
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import re
import csv

# # # # TWITTER CLIENT # # # #
class TwitterClient():
    def __init__(self, twitter_user=None):
        self.auth = TwitterAuthenticator().authenticate_twitter_app()
        self.twitter_client = API(self.auth)

        self.twitter_user = twitter_user

    def get_twitter_client_api(self):
        return self.twitter_client


# # # # TWITTER AUTHENTICATER # # # #
class TwitterAuthenticator():

    def authenticate_twitter_app(self):
        auth = OAuthHandler(credentials_from_twitter.CONSUMER_KEY, credentials_from_twitter.CONSUMER_SECRET)
        auth.set_access_token(credentials_from_twitter.ACCESS_TOKEN, credentials_from_twitter.ACCESS_TOKEN_SECRET)
        return auth

# # # # TWITTER STREAMER # # # #
class TwitterStreamer():
    """
    Class for streaming and processing live tweets.
    """
    def __init__(self):
        self.twitter_autenticator = TwitterAuthenticator()    

    def stream_tweets(self, fetched_tweets_filename):
        # This handles Twitter authetification and the connection to Twitter Streaming API
        listener = TwitterListener(fetched_tweets_filename)
        auth = self.twitter_autenticator.authenticate_twitter_app() 
        stream = Stream(auth, listener)

        # This line filter Twitter Streams to capture data by the keywords: 
        stream.filter(locations=[2.69170169436, 4.24059418377, 14.5771777686, 13.8659239771])


# # # # TWITTER STREAM LISTENER # # # #
class TwitterListener(StreamListener):
    """
    This is a basic listener that just prints received tweets to stdout.
    """
    def __init__(self, fetched_tweets_filename):
        self.fetched_tweets_filename = fetched_tweets_filename

    def on_data(self, data):
        try:
            print(data)
            with open(self.fetched_tweets_filename, 'a') as tf:
                #if 'Buhari' in self.fetched_tweets_filename:
                    tf.write(data)
            return True
        except BaseException as e:
            print("Error on_data %s" % str(e))
        return True

          
    def on_error(self, status):
        if status == 420:
            # Returning False on_data method in case rate limit occurs.
            return False
        print(status)


class TweetAnalyzer():
    """
    Functionality for analyzing and categorizing content from tweets.
    """

    def clean_tweet(self, tweet):
        return ' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t])|(\w+:\/\/\S+)", " ", tweet).split())

    def analyze_sentiment(self, tweet):
        analysis = TextBlob(self.clean_tweet(tweet))
        
        if analysis.sentiment.polarity > 0:
            return 1
        elif analysis.sentiment.polarity == 0:
            return 0
        else:
            return -1

    def tweets_to_data_frame(self, tweets):
        df = pd.DataFrame(data=[tweet.text for tweet in tweets], columns=['tweets'])

        df['id'] = np.array([tweet.id for tweet in tweets])
        df['len'] = np.array([len(tweet.text) for tweet in tweets])
        df['date'] = np.array([tweet.created_at for tweet in tweets])
        df['source'] = np.array([tweet.source for tweet in tweets])
        df['likes'] = np.array([tweet.favorite_count for tweet in tweets])
        df['retweets'] = np.array([tweet.retweet_count for tweet in tweets])
        

        return df


def set_up():
    with open('tweet.csv', 'w', encoding='utf-8-sig', newline='') as tf:
        writer = csv.writer(tf)
        writer.writerow(["tweets", "id", "len", "date", "source", "likes", "retweets"])
def write(tweets, id, len, date, source, likes, retweets):
    with open('tweet.csv', 'a', encoding='utf-8-sig', newline='') as tf:
        writer = csv.writer(tf)
        writer.writerow([tweets, id, len, date, source, likes, retweets])




 
if __name__ == '__main__':

    twitter_client = TwitterClient()
    tweet_analyzer = TweetAnalyzer()

    api = twitter_client.get_twitter_client_api()

    tweets = api.user_timeline(screen_name="OfficialAPCNg", max_id=1093515930905330000, count=20)
    #1199321187999981568,
    #23 RD FEBRUARY 2019 ELECTION DATE 1099243789837890000
    #27TH FEBRUARY 2019 USE THIS 1100604884234186752
    #25 JANUARY 1098137843128516609
    df = tweet_analyzer.tweets_to_data_frame(tweets)
    for ind in df.index:
        write(df['tweets'][ind], df['id'][ind], df['len'][ind], df['date'][ind], df['source'][ind], 
            df['likes'][ind], df['retweets'][ind])

    df2 = pd.read_csv('all_tweets.csv')

    #df['sentiment'] = np.array([tweet_analyzer.analyze_sentiment(tweet) for tweet in df2['tweets']])
    df['sentiment'] = np.array([tweet_analyzer.analyze_sentiment(tweet) for tweet in df2['tweets']])

    

    
    print(df.head())

    plt.style.use('ggplot')
    time_likes = pd.Series(data=df['likes'].values, index=df['date'])
    time_likes.plot(color='r', label="Likes")
    time_retweets = pd.Series(data=df['retweets'].values, index=df['date'])
    time_retweets.plot(color='b', label="Retweets")
    plt.title("Likes and Retweets for Tweets Analyzed From OfficailAPCNg", fontsize=15)
    plt.savefig('APC_LIKES_RETWEETS.png')
    plt.legend()
    plt.show()


    polarity = df['sentiment']
    
    p = sns.distplot(polarity, color="r",)
    p.set_title("APC Tweet Polarity", fontsize = 20)
    p.set_xlabel('← Negative — — — — Positive →', fontsize=15)
    plt.tight_layout()
    plt.savefig('distribution_plot_for_apc_polarity.png')
    plt.show()






    
    
    #Get the total of Positive, Negative and Neutral Sentiments for APC in OfficialAPCNg
    positive_sentiments = negative_sentiments = neutral_sentiments = 0
    for sentiment in df['sentiment']:
        if sentiment==1:
            positive_sentiments+=1
        elif sentiment==-1:
            negative_sentiments+=1
        else:
            neutral_sentiments+=1


    print("The Total Positive Sentiments (Sentiments Supporting APC) in OffialAPCNg is ",positive_sentiments, ".\n")
    print("The Total Negtative Sentiments (Sentiments Against APC) in OffialAPCNg is ",negative_sentiments, ".\n")
    print("The Total Neutral Sentiments (Sentiments that is Neutral) in OffialAPCNg is ",neutral_sentiments, ".")```
...