使用 Flask 的 Twitter 情绪分析 WebApp
这是一个使用Python和 Flask 框架制作的网络应用程序。它有一个注册系统和一个仪表板。用户可以输入关键字来检索基于关键字的实时 Twitter 文本,并对其进行分析以获取客户的感受和情绪。这些数据可以在图表中可视化。特别是,该项目使用流行的“Tweepy”API 挖掘数据。 Tweepy API 实时连接到 Twitter,并从 Twitter 平台收集元数据和文本。
目的:
- 帮助公司研究围绕特定产品的客户情绪。
- 帮助系统用户快速高效地分析海量数据。
- 以 -1 到 1 的比例区分客户情绪,其中 -1 表示对关键字的强烈负面情绪,1 表示强烈的正面反应。
- 清晰有效地可视化收集到的数据。
详细项目实施视频:
项目中使用的工具和技术:
硬件:
- 4GB 内存
- 视窗 10
- 用于部署的 Google Chrome 网络浏览器
- 用于连接到 Twitter 的 Internet 连接
本项目设计是基于软件的,因此硬件设计要求包括一台运行良好的 64 位 PC,具有至少 4 GB 的 RAM。
软件:
- Python- Python是一种解释型、高级和通用的编程语言。 Python了代码的可管理性和可读性,使其成为用于机器学习的顶级应用程序之一。
- Flask Web 框架(与Python)- Flask 是一个 Web 框架。这意味着 Flask 为我们提供了工具、库和技术,使我能够构建 Web 应用程序和网页。 Flask 是一个后端微框架,它使数据处理变得干净和简单。
- Tweepy( Python 的Twitter API)- Tweepy 是一个开源Python包,它为您提供了一种使用Python访问 Twitter API 的非常方便的方法。 Tweepy 包括一组表示 Twitter 模型和 API 端点的类和方法,它透明地处理各种实现细节,例如数据编码和解码。
- 适用于 Windows 的 Xampp 服务器上的 Apache SQL - SQL 服务器在本地主机内的 phpMyAdmin 上运行。该数据库用于存储、验证和检索用户的登录凭据。
- Bootstrap - 在 Bootstrap 的帮助下增强了 UI,它有助于构建现代、直观和响应式的网页。
- JQuery - JQuery 用于从 Tweepy API 来回发送和检索数据,并将结果显示在网页上。
- HTML/CSS- HTML 和 CSS 是网站前端设计的基础。
构建项目所需的技能:
- 机器学习 - 中等
- 编程技巧
- Python- 高级。
- HTML/CSS/JQUERY/BOOTSTRAP-基本到中等。
- SQL/DBMS-基本到中等
- 调试/部署 – 中等
- 使用 API 的能力。
实施项目:
按照以下步骤实施项目:
步骤 1:在您的系统上下载并安装 Xampp 服务器。
第 2 步:启动 Apache Xampp 和 MySQL。在 MySQL 中创建一个包含 3 列(用户名、电子邮件 ID 和密码)的数据库。
第 3 步:下载并安装 PyCharm。单击“创建”->“新建项目”。为您的项目命名。
第 4 步:在 Pycharm 中键入以下代码。有关详细的项目文件和层次结构,请参阅此 GitHub 存储库。
main.py 文件:
在这个文件中,我们首先初始化我们的项目。我们使用“conn”对象建立到我们的 SQL 数据库的连接。
我们设置了一个用户 cookie 变量,在将他/她重定向到主页之前,它会检查用户是否已登录。该脚本还处理登录/注册页面上的用户输入。
Python3
from flask import Flask, render_template, request, redirect, session
import mysql.connector
from sentiments import second
import os
app = Flask(__name__)
# initializing the user cookie
app.secret_key = os.urandom(24)
# blueprint to call the second python file in the project.
app.register_blueprint(second)
# establishing a connection with mysql database made in xampp
try:
conn = mysql.connector.connect(
host="localhost", user="root", password="", database="users")
cursor = conn.cursor()
except:
print("An exception occured")
# call the login template when the url is http://localhost:5000/
@app.route('/')
def login():
return render_template('login.html')
# call the register template when the url is http://localhost:5000/register
@app.route('/register')
def register():
return render_template('register.html')
@app.route('/home')
def home():
if 'user_id' in session:
return render_template('home.html')
else:
return redirect('/')
@app.route('/login_validation', methods=['POST'])
def login_validation():
email = request.form.get('email')
password = request.form.get('password')
cursor.execute(
"""SELECT * from `users` WHERE `email` LIKE '{}' AND `password` LIKE '{}'""".format(email, password))
users = cursor.fetchall()
# check if a user has already logged in
if len(users) > 0:
session['user_id'] = users[0][0]
return redirect('/home')
else:
return redirect('/login')
@app.route('/add_user', methods=['POST'])
def add_user():
# get user login data and pass the data to database
name = request.form.get('uname')
email = request.form.get('uemail')
password = request.form.get('upassword')
cursor.execute("""INSERT INTO `users` (`name`,`email`,`password`) VALUES ('{}','{}','{}')""".format(
name, email, password))
conn.commit()
cursor.execute(
"""SELECT * from `users` WHERE `email` LIKE '{}'""".format(email))
myuser = cursor.fetchall()
session['user_id'] = myuser[0][0]
return redirect('/home')
@app.route('/logout')
def logout():
# close the session
session.pop('user_id')
return redirect('/')
if __name__ == "__main__":
app.run(debug=True)
Python3
from flask import Blueprint, render_template, request
import matplotlib.pyplot as plt
import os
import tweepy
import csv
import re
from textblob import TextBlob
import matplotlib
matplotlib.use('agg')
# register this file as a blueprint
second = Blueprint("second", __name__, static_folder="static",
template_folder="template")
# render page when url is called
@second.route("/sentiment_analyzer")
def sentiment_analyzer():
return render_template("sentiment_analyzer.html")
# class with main logic
class SentimentAnalysis:
def __init__(self):
self.tweets = []
self.tweetText = []
# This function first connects to the Tweepy API using API keys
def DownloadData(self, keyword, tweets):
# authenticating
consumerKey = '//get from Tweepy'
consumerSecret = '//get from Tweepy'
accessToken = '//insert your access token here'
accessTokenSecret = '//Tweepy AccessToken secret here'
auth = tweepy.OAuthHandler(consumerKey, consumerSecret)
auth.set_access_token(accessToken, accessTokenSecret)
api = tweepy.API(auth, wait_on_rate_limit=True)
# input for term to be searched and how many tweets to search
# searchTerm = input("Enter Keyword/Tag to search about: ")
# NoOfTerms = int(input("Enter how many tweets to search: "))
tweets = int(tweets)
# searching for tweets
self.tweets = tweepy.Cursor(
api.search, q=keyword, lang="en").items(tweets)
# Open/create a file to append data to
csvFile = open('result.csv', 'a')
# Use csv writer
csvWriter = csv.writer(csvFile)
# creating some variables to store info
polarity = 0
positive = 0
wpositive = 0
spositive = 0
negative = 0
wnegative = 0
snegative = 0
neutral = 0
# iterating through tweets fetched
for tweet in self.tweets:
# Append to temp so that we can store in csv later. I use encode UTF-8
self.tweetText.append(self.cleanTweet(tweet.text).encode('utf-8'))
# print (tweet.text.translate(non_bmp_map)) #print tweet's text
analysis = TextBlob(tweet.text)
# print(analysis.sentiment) # print tweet's polarity
# adding up polarities to find the average later
polarity += analysis.sentiment.polarity
# adding reaction of how people are reacting to find average later
if (analysis.sentiment.polarity == 0):
neutral += 1
elif (analysis.sentiment.polarity > 0 and analysis.sentiment.polarity <= 0.3):
wpositive += 1
elif (analysis.sentiment.polarity > 0.3 and analysis.sentiment.polarity <= 0.6):
positive += 1
elif (analysis.sentiment.polarity > 0.6 and analysis.sentiment.polarity <= 1):
spositive += 1
elif (analysis.sentiment.polarity > -0.3 and analysis.sentiment.polarity <= 0):
wnegative += 1
elif (analysis.sentiment.polarity > -0.6 and analysis.sentiment.polarity <= -0.3):
negative += 1
elif (analysis.sentiment.polarity > -1 and analysis.sentiment.polarity <= -0.6):
snegative += 1
# Write to csv and close csv file
csvWriter.writerow(self.tweetText)
csvFile.close()
# finding average of how people are reacting
positive = self.percentage(positive, tweets)
wpositive = self.percentage(wpositive, tweets)
spositive = self.percentage(spositive, tweets)
negative = self.percentage(negative, tweets)
wnegative = self.percentage(wnegative, tweets)
snegative = self.percentage(snegative, tweets)
neutral = self.percentage(neutral, tweets)
# finding average reaction
polarity = polarity / tweets
# printing out data
# print("How people are reacting on " + keyword + " by analyzing " + str(tweets) + " tweets.")
# print()
# print("General Report: ")
if (polarity == 0):
htmlpolarity = "Neutral"
# print("Neutral")
elif (polarity > 0 and polarity <= 0.3):
htmlpolarity = "Weakly Positive"
# print("Weakly Positive")
elif (polarity > 0.3 and polarity <= 0.6):
htmlpolarity = "Positive"
elif (polarity > 0.6 and polarity <= 1):
htmlpolarity = "Strongly Positive"
elif (polarity > -0.3 and polarity <= 0):
htmlpolarity = "Weakly Negative"
elif (polarity > -0.6 and polarity <= -0.3):
htmlpolarity = "Negative"
elif (polarity > -1 and polarity <= -0.6):
htmlpolarity = "strongly Negative"
self.plotPieChart(positive, wpositive, spositive, negative,
wnegative, snegative, neutral, keyword, tweets)
print(polarity, htmlpolarity)
return polarity, htmlpolarity, positive, wpositive, spositive, negative, wnegative, snegative, neutral, keyword, tweets
def cleanTweet(self, tweet):
# Remove Links, Special Characters etc from tweet
return ' '.join(re.sub("(@[A-Za-z0-9]+)|([^0-9A-Za-z \t]) | (\w +:\ / \ / \S +)", " ", tweet).split())
# function to calculate percentage
def percentage(self, part, whole):
temp = 100 * float(part) / float(whole)
return format(temp, '.2f')
# function which sets and plots the pie chart. The chart is saved in an img file every time the project is run.
# The previous image is overwritten. This image is called in the html page.
def plotPieChart(self, positive, wpositive, spositive, negative, wnegative, snegative, neutral, keyword, tweets):
fig = plt.figure()
labels = ['Positive [' + str(positive) + '%]', 'Weakly Positive [' + str(wpositive) + '%]',
'Strongly Positive [' + str(spositive) +
'%]', 'Neutral [' + str(neutral) + '%]',
'Negative [' + str(negative) +
'%]', 'Weakly Negative [' + str(wnegative) + '%]',
'Strongly Negative [' + str(snegative) + '%]']
sizes = [positive, wpositive, spositive,
neutral, negative, wnegative, snegative]
colors = ['yellowgreen', 'lightgreen', 'darkgreen',
'gold', 'red', 'lightsalmon', 'darkred']
patches, texts = plt.pie(sizes, colors=colors, startangle=90)
plt.legend(patches, labels, loc="best")
plt.axis('equal')
plt.tight_layout()
strFile = r"C:\Users\LENOVO\PycharmProjects\SentimentAnalysis\static\images\plot1.png"
if os.path.isfile(strFile):
os.remove(strFile) # Opt.: os.system("rm "+strFile)
plt.savefig(strFile)
plt.show()
@second.route('/sentiment_logic', methods=['POST', 'GET'])
def sentiment_logic():
# get user input of keyword to search and number of tweets from html form.
keyword = request.form.get('keyword')
tweets = request.form.get('tweets')
sa = SentimentAnalysis()
# set variables which can be used in the jinja supported html page
polarity, htmlpolarity, positive, wpositive, spositive, negative, wnegative, snegative, neutral, keyword1, tweet1 = sa.DownloadData(
keyword, tweets)
return render_template('sentiment_analyzer.html', polarity=polarity, htmlpolarity=htmlpolarity, positive=positive, wpositive=wpositive, spositive=spositive,
negative=negative, wnegative=wnegative, snegative=snegative, neutral=neutral, keyword=keyword1, tweets=tweet1)
@second.route('/visualize')
def visualize():
return render_template('PieChart.html')
HTML
Home
Twitter Sentiment Analysis
Need help? Click here
-----------------------------------------------------------------------------------
{% if polarity %}
How are people reacting on {{keyword}} by analyzing {{tweets}} Tweets
{% endif %}
General Report
{% if polarity %}
The Average Sentiment is {{htmlpolarity}}
{%endif%}
Sentiment Polarity
{% if polarity %}
The sentiment polarity is {{polarity}}
{%endif%}
Detailed Report
{% if polarity %}
{{spositive}} "% people thought it was strongly positive"
{{positive}} "% people thought it was positive"
{{wpositive}} "% people thought it was weakly positive"
{{neutral}} "% people thought it was neutral"
{{negative}} "% people thought it was negative"
{{wnegative}} "% people thought it was weakly negative"
{{snegative}} "% people thought it was strongly negative"
{%endif%}
Generate Visualization
HTML
Login
Welcome to this Twitter Sentiment Analysis!
Not a member? Create Account
HTML
Registration
Welcome to this Twitter Sentiment Analysis!
Already a member? Login
HTML
HTML
Data Visualization
Twitter Sentiment Analysis
** Last generated visual. Press CTRL+ Refresh to reload
Back