【毕业设计】基于大数据的电影数据爬取分析可视化系统

文章目录

0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 基于大数据的电影数据爬取分析可视化系统

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:4分
  • 工作量:4分
  • 创新点:3分

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md

1 课题背景

随着互联网的快速发展,越来越多的人喜欢在微博、知乎、豆瓣等社交网站上发表自己对某些事物的想法、态度或意见。用户同时也会将自己购买的产品或体验到的服务,在这些社区式的网站上评价,这样通常会带动他人也前去购买或体验,形成口碑效应。

社交应用及网站上有源源不断的信息发布,这些信息中隐含着大量对我们及企业有收集价值的资源。就像用户评分和评价系统中,用户不但会对作品进行评比,还分享和传播了作品信息。如果能够获取这些数据并对其进行分析,可以让人们挑选到满意的书籍、选择出一部精彩的电影,也可以帮助企业改进产品的服务等。使用爬虫程序可以高效地对社交网站上的信息进行收集、组织和管理。豆瓣网作为社交网站的代表,提供了在图书、电影和音乐等方面独树一帜的评分、推荐及比价体系,在社交网络中产生了深远的影响。

2 项目效果展示

2.1 主界面展示

【毕业设计】基于大数据的电影数据爬取分析可视化系统

; 2.2电影数据查询

管理员可对电影数据进行查询,可根据”最低评分”,”最高评分”,”上映年份”,”电影类型”,”上映地区”,”影名关键字”等标签进行筛选、查询。

【毕业设计】基于大数据的电影数据爬取分析可视化系统

2.3可视化展示

  • 电影类型矩形图:可以清楚的看到剧情,纪录片,喜剧类型的电影所占比重较大。

【毕业设计】基于大数据的电影数据爬取分析可视化系统
  • 上映年份漏斗图:可以看到中国、美国上映地区较多。

【毕业设计】基于大数据的电影数据爬取分析可视化系统
  • 上映年份分布、电影评分分布图。

【毕业设计】基于大数据的电影数据爬取分析可视化系统

【毕业设计】基于大数据的电影数据爬取分析可视化系统
  • 时间轴图:可随年份动态变化效果。

【毕业设计】基于大数据的电影数据爬取分析可视化系统
  • 地区类型分布饼状图

【毕业设计】基于大数据的电影数据爬取分析可视化系统
  • 频数统计词云图:可根据主演、导演、编剧和电影排名生成相应的词云图

【毕业设计】基于大数据的电影数据爬取分析可视化系统

; 3 数据爬取

3.1 Requests

requests是Python用于网络请求的第三库,也是爬虫获取网络数据的重要工具,使用的时候需要导入

本项目中相关代码:

import requests
from bs4 import BeautifulSoup
from lxml import html

etree = html.etree
import csv

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"
}
hrefs = []

def get_film_url(url):
    try:
        r = requests.get(url, headers=headers)
        selector = etree.HTML(r.text)
        movie_hrefs = selector.xpath('//div[@class="hd"]/a/@href')
        for i in range(0, len(movie_hrefs)):
            hrefs.append(movie_hrefs[i])
    except Exception as e:
        print(e)

def save_url():
    try:

        for href in hrefs:

            file_path = "./豆瓣电影TOP250链接.csv"
            with open(file_path, "a+", newline='', encoding='gb18030') as csvfile:
                writer = csv.writer(csvfile)
                writer.writerow([href])
    except Exception as e:
        print(e)

def main():

    for i in range(0, 250, 25):
        url = "https://movie.douban.com/top250?start=" + str(i) + ""
        get_film_url(url)
    save_url()

if __name__ == '__main__':
    main()

3.2 bs4

bs4即BeautifulSoup,是python种的一个库,最主要的内容就是从网页中抓取数据。

Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。

Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。

Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。

3.3 MySQL数据库

利用Pymysql,将爬取到的数据存入数据库中,相关代码如下:


        conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='douban', charset='utf8')

        cursor = conn.cursor()

        query = 'insert into tb_film(url, filmname, score, showtime, genres, areas, directors, scriptwriters, actors, comments) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'

        values = (
            url, filmname, score, showtime, genres_list, area_list,  directors_list, scriptwriters_list,
            actors_list,
            comment)
        cursor.execute(query, values)

        conn.commit()

4 可视化技术

4.1 Flask

Flask是一个基于Werkzeug和Jinja2的轻量级Web应用程序框架。与其他同类型框架相比,Flask的灵活性、轻便性和安全性更高,而且容易上手,它可以与MVC模式很好地结合进行开发。Flask也有强大的定制性,开发者可以依据实际需要增加相应的功能,在实现丰富的功能和扩展的同时能够保证核心功能的简单。Flask丰富的插件库能够让用户实现网站定制的个性化,从而开发出功能强大的网站。

本项目在Flask开发后端时,前端请求会遇到跨域的问题,解决该问题有修改数据类型为jsonp,采用GET方法,或者在Flask端加上响应头等方式,在此使用安装Flask-CORS库的方式解决跨域问题。此外需要安装请求库axios。

部分相关代码:

from flask import Flask
from flask import request, redirect
from flask import render_template, url_for
from flask_paginate import Pagination
from sqlalchemy import create_engine,Column,Integer,SmallInteger,String
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
from list_data import select_score, select_showtime, select_genres, select_areas, film_data
from genres import show_genres
from areas import show_areas
from showtime import show_showtime
from score import show_score
from timeline_score import show_score_top
from timeline_comment import show_comment_top
from select_showtime import select_showtime
from select_showtime import showtime_group
from film_search import film_search

app = Flask(__name__)
app.jinja_env.auto_reload = True
app.config['TEMPLATES_AUTO_RELOAD'] = True

engine = create_engine("mysql+pymysql://root:123456@localhost:3306/douban?charset=utf8",echo = True)

Session =sessionmaker(bind=engine)
session =Session

Base = declarative_base()

class Film(Base):

    __tablename__= 'tb_film'

    id = Column(Integer,primary_key=True,autoincrement=True)
    url =Column(String(250))
    filmname =Column(String(50))
    score =Column(String)
    comments =Column(Integer)
    showtime =Column(Integer)
    genres =Column(String(20))
    areas =Column(String(20))
    actors =Column(String(50))
    directors =Column(String(50))
    scriptwriters =Column(String(50))

@app.route('/')
def index():

    return render_template('login.html')

@app.route('/register')
def register():

    return render_template('register.html')

@app.route('/index')
def welcom2index():

    return render_template('index.html')

@app.route('/welcome')
def welcome():
    print('done')
    return render_template('pages/welcome.html')

@app.route("/page_none")
def page_none():
    return render_template('page_none')

@app.route('/login', methods=['POST'])

def login():
    print(request.form['username'])

    if request.form['username'] == 'admin' and request.form['password'] == '123456':
        return render_template('index.html')

@app.route("/list")
@app.route("/list/")
def list(limit=10):

    t_low = select_score()[0]
    t_high = select_score()[1]
    t_showtime = select_showtime()
    t_genres = select_genres()
    t_areas = select_areas()

    page = int(request.args.get("page", 1))
    start = (page - 1) * limit
    if request.args.get("low") or request.args.get("high") or request.args.get("showtime") or request.args.get("areas") or request.args.get("genres") or request.args.get("filmname"):

        r_low = request.args.get("low")
        r_high = request.args.get("high")
        r_showtime = request.args.get("showtime")
        r_genres = request.args.get("genres")
        r_areas = request.args.get("areas")
        r_filmname = request.args.get("filmname")

        print("参数:{},{},{},{},{}".format(r_low, r_high, r_showtime, r_genres, r_areas,r_filmname))
        print("参数1:{}".format(type(r_low)))
        print("参数2:{}".format(len(r_low)))
        r_films = film_data(low=r_low, high=r_high, showtime=r_showtime, genres=r_genres, areas=r_areas, filmname=r_filmname)[0]
        r_row = film_data(low=r_low, high=r_high, showtime=r_showtime, genres=r_genres, areas=r_areas, filmname=r_filmname)[1]

        r_end = page * limit if r_row > page * limit else r_row
        r_paginate = Pagination(page=page, total=r_row)
        r_ret = r_films[start:r_end]
        return render_template('pages/order/list.html', low=t_low, high=t_high, showtime=t_showtime, genres=t_genres,
                           areas=t_areas, films=r_ret, row=r_row,paginate=r_paginate)
    else:

        films = film_data()[0]
        row = film_data()[1]
        end = page * limit if row > page * limit else row
        paginate = Pagination(page=page, total=row)
        ret=films[start:end]
        print("res:{}".format(ret))
        return render_template('pages/order/list.html', low=t_low, high=t_high, showtime=t_showtime, genres=t_genres,
                           areas=t_areas, films=ret,row=row, paginate=paginate)

4.2 ECharts

ECharts(Enterprise Charts)是百度开源的数据可视化工具,底层依赖轻量级Canvas库ZRender。兼容了几乎全部常用浏览器的特点,使它可广泛用于PC客户端和手机客户端。ECharts能辅助开发者整合用户数据,创新性的完成个性化设置可视化图表。支持折线图(区域图)、柱状图(条状图)、散点图(气泡图)、K线图、饼图(环形图)等,通过导入 js 库在 Java Web 项目上运行。

数据预览

import pandas as pd
import json

credits = pd.read_csv('./tmdb_5000_credits.csv')
print('credits:\n', credits)
print('*' * 100)
print('credits:\n', credits.columns)
print('*' * 100)
print('credits:\n', credits.info())
print('*' * 100)

movies = pd.read_csv('./tmdb_5000_movies.csv')
print('movies:\n', movies)
print('#' * 100)
print('movies:\n', movies.columns)
print('#' * 100)
print('movies:\n', movies.info())
print('#' * 100)

【毕业设计】基于大数据的电影数据爬取分析可视化系统

合并数据集

先将 credits 数据集和 movie 数据集中的数据合并在一起,再查看合并后的数据集信息

代码实现:


credits.rename(columns={'movie_id': 'id'}, inplace=True)

all_data = pd.merge(left=credits, right=movies, on=['id', 'title'], how='outer')
print('all_data:\n', all_data)
print('all_data:\n', all_data.columns)
print('all_data:\n', all_data.dtypes)

选取子集

由于数据集中包含的信息过多,其中部分数据并不是我们研究的重点,所以从中选取我 们需要的数据:

代码实现:


all_data = all_data['original_title', 'crew', 'release_date', 'genres', 'keywords',
                    'production_companies', 'production_countries', 'revenue',
                    'budget', 'runtime', 'vote_average']
print('all_data的列索引:\n', all_data.columns)
print('all_data的形状:\n', all_data.shape)

由于后面的数据分析涉及到电影类型的利润计算,先求出每部电影的利润,并在数据集 data 中增加 profit 数据列

代码实现:


all_data['profit'] = all_data['revenue'] - all_data['budget']
print('all_data的列索引:\n', all_data)
print('all_data的形状:\n', all_data)

缺失值处理

代码实现:


res_null = pd.isnull(all_data).sum()
print('缺失值检测结果:\n', res_null)

mask = all_data.loc[:, 'release_date'].isnull()

movie_name = all_data.loc[mask, 'title']
print('缺失上映日期的电影名称为:\n', movie_name)

all_data.loc[mask, 'release_date'] = '2014-06-01'

all_data.loc[:, 'release_date'] = pd.to_datetime(all_data.loc[:, 'release_date'])

all_data.loc[:, 'release_year'] = all_data.loc[:, 'release_date'].dt.year

通过上面的结果信息可以知道:整个数据集缺失的数据比较少。 其中 release_date(首次上映日期)缺失 1 个数据,可以通过网上查询补齐这个数据,填补 release_date(首次上映日期)数据

数据格式转换

genres 列数据处理:

代码实现:


print('电影风格:\n', all_data.loc[:, 'genres'])

all_data.loc[:, 'genres'] = all_data.loc[:, 'genres'].transform(json.loads)

all_movie_type = set()

def get_movie_type(val):
"""
    获取电影类型
    :param val: 数据
    :return: 提取之后的电影类型数据
"""

    type_list = []

    for item in val:

        if item:

            movie_type = item['name']

            type_list.append(movie_type)

            all_movie_type.add(movie_type)

    return ','.join(type_list)

all_data.loc[:, 'genres'] = all_data.loc[:, 'genres'].transform(get_movie_type)

print('获取电影类型之后的结果:\n', all_data.loc[:, 'genres'])

all_movie_type = list(all_movie_type)

for column in all_movie_type:

    all_data.loc[:, column] = 0

    mask = all_data.loc[:, 'genres'].str.contains(column)

    all_data.loc[mask, column] = 1

print('all_data:\n', all_data)

数据可视化

绘制电影数据类型随时间变化趋势图

import matplotlib.pyplot as plt

plt.figure()

plt.rcParams['font.sans-serif'] = 'SimHei'

plt.rcParams['axes.unicode_minus'] = False

x = groupby_year.index
for movie_type in groupby_year.columns:

    y = groupby_year[movie_type]

    plt.plot(x, y)

plt.title('电影数据类型随时间变化趋势图')

plt.legend(groupby_year.columns, fontsize='x-small')

plt.ylabel('数量')

plt.xlabel('年份')

plt.grid(b=True, alpha=0.2)

plt.savefig('./电影数据类型随时间变化')

plt.show()

【毕业设计】基于大数据的电影数据爬取分析可视化系统
分析结论: 从图中观察到,随着时间的推移,所有电影类型都呈现出增长趋势,尤其是 1992 年以 后各个类型的电影均增长迅速,其中 Drama(戏剧)和 Comedy(喜剧)增长最快,目前仍是最热 门的电影类型

绘制各种类型电影数量的统计柱状图

【毕业设计】基于大数据的电影数据爬取分析可视化系统

绘制各种电影类型的占比饼图

【毕业设计】基于大数据的电影数据爬取分析可视化系统

电影类型平均利润数据可视化


bar = Bar(

    init_opts=opts.InitOpts(
        width='900px',
        height='600px',
        theme="white"
    )
)

bar.add_xaxis(
    xaxis_data=res_series.index.tolist()
)

bar.add_yaxis(
    series_name=' ',
    yaxis_data=[float('%.2f' % i) for i in (res_series / 1000000)],
    color='#6495ED'
)

bar.set_global_opts(

    title_opts=opts.TitleOpts(
        title='各种电影类型利润统计柱状图',

        pos_left='center',
        pos_top='3%'
    ),

    legend_opts=opts.LegendOpts(
        is_show=False,
    ),

    xaxis_opts=opts.AxisOpts(
        name='利润(百万)'
    ),

    yaxis_opts=opts.AxisOpts(
        name='电影类型'
    )
)

bar.set_series_opts(
    label_opts=opts.LabelOpts(
        is_show=True,
        position='right',
        color='#000000',
        formatter='{c}'
    )
)

bar.reversal_axis()

bar.render('./各种电影类型利润统计柱状图.html')

【毕业设计】基于大数据的电影数据爬取分析可视化系统

分析结论:

从图中观察到,拍摄 Animation、Adventure、Fantasy 这三类电影盈利最好,而拍摄 Foreign、TV Movie 这两类电影会存在亏本的风险

未完待续。。。。。。

补充:不做成web系统

数据预览

import pandas as pd
import json

credits = pd.read_csv('./tmdb_5000_credits.csv')
print('credits:\n', credits)
print('*' * 100)
print('credits:\n', credits.columns)
print('*' * 100)
print('credits:\n', credits.info())
print('*' * 100)

movies = pd.read_csv('./tmdb_5000_movies.csv')
print('movies:\n', movies)
print('#' * 100)
print('movies:\n', movies.columns)
print('#' * 100)
print('movies:\n', movies.info())
print('#' * 100)

【毕业设计】基于大数据的电影数据爬取分析可视化系统

合并数据集

先将 credits 数据集和 movie 数据集中的数据合并在一起,再查看合并后的数据集信息

代码实现:


credits.rename(columns={'movie_id': 'id'}, inplace=True)

all_data = pd.merge(left=credits, right=movies, on=['id', 'title'], how='outer')
print('all_data:\n', all_data)
print('all_data:\n', all_data.columns)
print('all_data:\n', all_data.dtypes)

选取子集

由于数据集中包含的信息过多,其中部分数据并不是我们研究的重点,所以从中选取我 们需要的数据:

代码实现:


all_data = all_data['original_title', 'crew', 'release_date', 'genres', 'keywords',
                    'production_companies', 'production_countries', 'revenue',
                    'budget', 'runtime', 'vote_average']
print('all_data的列索引:\n', all_data.columns)
print('all_data的形状:\n', all_data.shape)

由于后面的数据分析涉及到电影类型的利润计算,先求出每部电影的利润,并在数据集 data 中增加 profit 数据列

代码实现:


all_data['profit'] = all_data['revenue'] - all_data['budget']
print('all_data的列索引:\n', all_data)
print('all_data的形状:\n', all_data)

缺失值处理

代码实现:


res_null = pd.isnull(all_data).sum()
print('缺失值检测结果:\n', res_null)

mask = all_data.loc[:, 'release_date'].isnull()

movie_name = all_data.loc[mask, 'title']
print('缺失上映日期的电影名称为:\n', movie_name)

all_data.loc[mask, 'release_date'] = '2014-06-01'

all_data.loc[:, 'release_date'] = pd.to_datetime(all_data.loc[:, 'release_date'])

all_data.loc[:, 'release_year'] = all_data.loc[:, 'release_date'].dt.year

通过上面的结果信息可以知道:整个数据集缺失的数据比较少。 其中 release_date(首次上映日期)缺失 1 个数据,可以通过网上查询补齐这个数据,填补 release_date(首次上映日期)数据

数据格式转换

genres 列数据处理:

代码实现:


print('电影风格:\n', all_data.loc[:, 'genres'])

all_data.loc[:, 'genres'] = all_data.loc[:, 'genres'].transform(json.loads)

all_movie_type = set()

def get_movie_type(val):
"""
    获取电影类型
    :param val: 数据
    :return: 提取之后的电影类型数据
"""

    type_list = []

    for item in val:

        if item:

            movie_type = item['name']

            type_list.append(movie_type)

            all_movie_type.add(movie_type)

    return ','.join(type_list)

all_data.loc[:, 'genres'] = all_data.loc[:, 'genres'].transform(get_movie_type)

print('获取电影类型之后的结果:\n', all_data.loc[:, 'genres'])

all_movie_type = list(all_movie_type)

for column in all_movie_type:

    all_data.loc[:, column] = 0

    mask = all_data.loc[:, 'genres'].str.contains(column)

    all_data.loc[mask, column] = 1

print('all_data:\n', all_data)

数据可视化

绘制电影数据类型随时间变化趋势图

import matplotlib.pyplot as plt

plt.figure()

plt.rcParams['font.sans-serif'] = 'SimHei'

plt.rcParams['axes.unicode_minus'] = False

x = groupby_year.index
for movie_type in groupby_year.columns:

    y = groupby_year[movie_type]

    plt.plot(x, y)

plt.title('电影数据类型随时间变化趋势图')

plt.legend(groupby_year.columns, fontsize='x-small')

plt.ylabel('数量')

plt.xlabel('年份')

plt.grid(b=True, alpha=0.2)

plt.savefig('./电影数据类型随时间变化')

plt.show()

【毕业设计】基于大数据的电影数据爬取分析可视化系统
分析结论: 从图中观察到,随着时间的推移,所有电影类型都呈现出增长趋势,尤其是 1992 年以 后各个类型的电影均增长迅速,其中 Drama(戏剧)和 Comedy(喜剧)增长最快,目前仍是最热 门的电影类型

绘制各种类型电影数量的统计柱状图

【毕业设计】基于大数据的电影数据爬取分析可视化系统

绘制各种电影类型的占比饼图

【毕业设计】基于大数据的电影数据爬取分析可视化系统

电影类型平均利润数据可视化


bar = Bar(

    init_opts=opts.InitOpts(
        width='900px',
        height='600px',
        theme="white"
    )
)

bar.add_xaxis(
    xaxis_data=res_series.index.tolist()
)

bar.add_yaxis(
    series_name=' ',
    yaxis_data=[float('%.2f' % i) for i in (res_series / 1000000)],
    color='#6495ED'
)

bar.set_global_opts(

    title_opts=opts.TitleOpts(
        title='各种电影类型利润统计柱状图',

        pos_left='center',
        pos_top='3%'
    ),

    legend_opts=opts.LegendOpts(
        is_show=False,
    ),

    xaxis_opts=opts.AxisOpts(
        name='利润(百万)'
    ),

    yaxis_opts=opts.AxisOpts(
        name='电影类型'
    )
)

bar.set_series_opts(
    label_opts=opts.LabelOpts(
        is_show=True,
        position='right',
        color='#000000',
        formatter='{c}'
    )
)

bar.reversal_axis()

bar.render('./各种电影类型利润统计柱状图.html')

【毕业设计】基于大数据的电影数据爬取分析可视化系统

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md

5 最后

Original: https://blog.csdn.net/HUXINY/article/details/125845148
Author: DanCheng-studio
Title: 【毕业设计】基于大数据的电影数据爬取分析可视化系统

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/696575/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球