毕业设计之 - 题目:基于大数据的电影数据分析可视化系统

Posted DanCheng-studio

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了毕业设计之 - 题目:基于大数据的电影数据分析可视化系统相关的知识,希望对你有一定的参考价值。

1 前言

Hi,大家好,这里是丹成学长,今天做一个电商销售预测分析,这只是一个demo,尝试对电影数据进行分析,并可视化系统

毕设帮助,开题指导,技术解答
🇶746876041

2 项目介绍

首先通过网页开发者工具分析豆瓣电影网站,然后使用抓包工具拦截数据,从中找出api接口,接下来使用Python爬虫进行数据的下载。数据下载完后,使用pandas模块处理csv电影数据文件,之后可以选用各种数据分析的方法对数据进行挖掘,包括但不限于关键词提炼、词频统计、相关性探索、电影分类,再通过matplotlib绘制数据统计图如条形图、饼状图,亦或是wordCloud绘制评论词云。

3 效果展示


4 项目分析

4.1 爬虫部分

豆瓣电影官网虽然没有令人窒息的反爬操作,但是接口较为隐蔽,需要通过Fiddler抓包工具辅助,才能找到电影数据接口。

编写爬虫时使用xpath对网页数据进行提取,使用正则表达式过滤冗余文本数据并对文本进行清洗。爬虫运行过程中要控制爬取速度,否则在运行时不会出现爬取问题,但经过一段时间后豆瓣官网检测到本台主机IP的不正常请求,就会对IP进行封锁,阻止下一次大规模爬取。

通过登录豆瓣账号获得Cookie可以减缓这一点,并且可以访问到更多的数据量,不过并不能保证不会被封号。最后将爬取数据保存为csv文件,方便后期使用pandas等做数据处理。


## 非完整代码,毕业设计找丹成学长,q746876041

import csv
import pymysql
import requests
import re
from lxml import html
import time

# 请求头
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"
}

# 读取电影url
urls = []
with open('./豆瓣电影TOP250链接.csv', 'r') as f:
    reader = csv.reader(f)
    urls = [row[0] for row in reader]

for i in range(0, len(urls)):
    url = urls[i]
    # 请求页面
    r = requests.get(url=url, headers=headers, timeout=5)
    time.sleep(2)
    etree = html.etree
    selector = etree.HTML(r.text)

    # 获取电影名称
    filmname = []
    try:
        filmname = selector.xpath('//*[@id="content"]/h1/span[1]/text()')[0]  # 电影名
        if filmname == "":
            filmname = None
    except Exception as e:
        filmname = None
    print("filmname :{}".format(filmname))

    # 获取电影评分
    score = []
    try:
        score_list = selector.xpath('//*[@id="interest_sectl"]/div[1]/div[2]/strong/text()')
        score = score_list[0].replace("\\t", "").replace("\\n", "")
        if score == "":
            score = None
    except Exception as e:
        score = None
    print("score :{}".format(score))

    # 获取电影上映时间
    showtime = []
    try:
        st = selector.xpath('//*[@id="content"]/h1/span[2]/text()')[0]  # 上映日期
        showtime = st.replace("(", "").replace(")", "")
        if showtime == "":
            showtime = None
    except Exception as e:
        showtime = None
    print("time :{}".format(showtime))

    # 获取电影片长
    mins = []
    try:
        mins_list = re.findall('片长:</span>.*?>(.*?)</span>', r.text, re.S)  # 片长
        mins = mins_list[0].replace(' ', '').replace('分钟', '')
        if mins == "":
            mins = None
    except Exception as e:
        mins = None
    print("mins :{}".format(mins))

    # 获取电影类型
    genres_list = []
    try:
        genres_list = re.findall('<span property="v:genre">(.*?)</span>', r.text, re.S)
        genres_list = '/'.join(genres_list)
        if genres_list == "":
            genres_list = None
    except Exception as e:
        genres_list = None
    print("genres_list :{}".format(genres_list))

    # 获取电影制片地区
    area_list = []
    try:
        area_list = re.findall('<span class="pl">制片国家/地区:</span> (.*?)<br/>', r.text, re.S)
        area_list = '/'.join(area_list).replace(' ', '')
        if area_list == "":
            area_list = None
    except Exception as e:
        area_list = None
    print("area_list :{}".format(area_list))

    # 获取电影导演
    directors_list = []
    try:
        d_list = selector.xpath('//div[@id="info"]/span[1]/span[2]/a/text()')  # 导演
        if len(d_list) > 2:
            for i in range(0, 3):
                directors_list.append(d_list[i])
        else:
            for j in range(0, len(d_list)):
                directors_list.append(d_list[j])
        directors_list = '/'.join(directors_list)
        if directors_list == "":
            directors_list = None
    except Exception as e:
        directors_list = None
    print("directors_list :{}".format(directors_list))

    # 获取电影编剧
    scriptwriters_list = []
    try:
        w_list = selector.xpath('//*[@id="info"]/span[2]/span[2]/a/text()')  # 编剧
        if len(w_list) > 2:
            for i in range(0, 3):
                scriptwriters_list.append(w_list[i])
        else:
            for j in range(0, len(w_list)):
                scriptwriters_list.append(w_list[j])
        scriptwriters_list = '/'.join(scriptwriters_list)
        if scriptwriters_list == "":
            scriptwriters_list = None
    except Exception as e:
        scriptwriters_list = None
    print('scriptwriters_list :{}'.format(scriptwriters_list))

    # 获取电影主演
    actors_list = []
    try:
        actors = selector.xpath('//*[@id="info"]/span[3]/span[2]')[0]  # 演员
        a_list = actors.xpath('string(.)').replace(' ', '').split('/')  # 标签套标签,用string(.)同时获取所有文本
        if len(a_list) > 2:
            for i in range(0, 3):
                actors_list.append(a_list[i])
        else:
            for j in range(0, a_list):
                actors_list.append(a_list[j])
        actors_list = '/'.join(actors_list)
        if actors_list == "":
            actors_list = None
    except Exception as e:
        actors_list = None
    print('actors_list :{}'.format(actors_list))

    # 获取电影评价
    comment = []
    try:
        comment = selector.xpath('//*[@id="interest_sectl"]/div[1]/div[2]/div/div[2]/a/span/text()')[0]
        if comment == "":
            comment = None
    except Exception as e:
        comment = None
    print("comment :{}".format(comment))

    try:
        # 打开数据库连接
        conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='douban', charset='utf8')
        # 使用cursor方法创建一个游标
        cursor = conn.cursor()
        # # 执行sql语句
        query = 'insert into tb_film(url, filmname, score, showtime, genres, areas, mins, directors, scriptwriters, actors, comments) values(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
        values = (
            url, filmname, score, showtime, genres_list, area_list, mins, directors_list, scriptwriters_list,
            actors_list,
            comment)
        cursor.execute(query, values)
        # 提交之前的操作,如果之前已经执行多次的execute,那么就都进行提交
        conn.commit()
    except Exception as e:
        print(e)
        # 回滚
        conn.rollback()
    # 关闭cursor对象
    cursor.close()
    # 关闭数据库连接
    conn.close()
## 非完整代码,毕业设计找丹成学长,q746876041

爬虫输出如下:

4.2 数据分析部分

针对某部电影的数据分析

从不同时期影评人数、影评推荐指数、短评内容三个角度入手分析,不同时期的影评人数可以间接反映电影的热度,因为大多数人都是在电影刚上映观影完后写的影评;影评推荐指数可以直接看出观众对电影的喜好程度,对最热门的评论的汇总更能体现这部电影在大众中的影响力,而不是单靠官方给出的豆瓣评分;短评词云可以体现电影的许多要素,比如演员、题材、主要情节剧情、观众评价,可以让影迷马上把握该电影脉搏,从而决定这部电影是否值得一看。

随机多部电影的综合数据分析

如果说针对某部电影的分析是让影迷决定是否看该部电影,那么随机多部电影的综合分析结果就是指引影迷去观看哪部电影。使用随机序号生成器在热门电影列表中任意选择电影,然后可视化出电影评分排行榜、电影Top20高分排行榜,电影上映时间线和电影类型分布,多方位直观俯瞰热门电影行情。对于大众来说可以得知哪些电影近期更受欢迎,哪些电影评分高,电影在哪个时间段上映,从而发现自己喜欢的电影和属于自己的电影偏好。对于电影制作方,可以针对电影类型分布,保持哪些电影类型的产出,加大哪类电影的制作投入以顺应大众口味,甚至可以决策在什么时候上映哪些类型的电影能获得最大收益。

## 非完整代码,毕业设计找丹成学长,q746876041
import pymysql
from pyecharts import options as opts
from pyecharts.charts import Timeline, Bar, Grid

# 上映年份
showtime = []
# 查询中外电影上映年份
def select_showtime():
    try:
        # 打开数据库连接
        conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='douban', charset='utf8')
        # 使用cursor方法创建一个游标
        cursor = conn.cursor()
        # 查询数据表数据
        # 查询上映年份
        sql = "select distinct showtime from tb_film where showtime is not null order by showtime "
        cursor.execute(sql)
        rows = cursor.fetchall()
        showtime.clear()
        for row in rows:
            showtime.append(row[0])
        print(showtime)
    except Exception as e:
        print(e)
        # 回滚
        conn.rollback()
    finally:
        # 关闭cursor对象
        cursor.close()
        # 关闭数据库连接
        conn.close()
    return showtime


# 查询电影名称、评分
def select_film(i):
    # 电影名称集合
    filmname = []
    # 评分集合
    score = []
    try:
        # 打开数据库连接
        conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='123456', db='douban', charset='utf8')
        # cursorclass = pymysql.cursors.DictCursor
        # 使用cursor方法创建一个游标
        cursor = conn.cursor()
        # 查询数据表数据
        # 查找评分前十的电影名称、评分
        cursor.execute(
            "select filmname,score from tb_film where score is not null and showtime > 0 and showtime <= %s order by score desc limit 10",
            i)
        # 电影名称、评分集合
        film_list = cursor.fetchall()
        for row in film_list:
            # 电影名称集合
            filmname.append(row[0])
            # 评分集合
            score.append(row[1])
        filmname.reverse()
        score.reverse()
        # 最大值
        max_score = max(score)
        # 最小值
        min_score = min(score)
    except Exception as e:
        print(e)
        # 回滚
        conn.rollback()
    finally:
        # 关闭cursor对象
        cursor.close()
        # 关闭数据库连接
        conn.close()
    return filmname, score, max_score, min_score


def select_data(year):
    film_list = select_film(year)
    colors = [
        "#546570", "#c4ccd3", "#bda29a", "#ca8622", "#d48265",
        "#6e7074", "#749f83", "#61a0a8", "#2f4554", "#c23531",
        "#6e7074", "#749f83", "#61a0a8", "#2f4554", "#c23531"
    ]
    y = []
    for n in range(len(film_list[1])):
        y.append(
            opts.BarItem(
                name=film_list[0][n],
                value=film_list[1][n],
                itemstyle_opts=opts.ItemStyleOpts(color=colors[n]),
            )
        )
    return y


def show_score_top():
    # 查找上映年份集合
    showtime=select_showtime()
    # 生成时间轴的图
    timeline = Timeline(init_opts=opts.InitOpts(page_title="豆瓣电影TOP250-评分TOP10的电影", ))
    for year in showtime:
        film_tuple=select_film(year)
        date_list=select_data(year)
        timeline.add_schema(is_auto_play=True, play_interval=1000)
        # 柱状图初始化
        bar = Bar()
        # 横坐标
        bar.add_xaxis(film_tuple[0])
        # 纵坐标
        bar.add_yaxis(
            "",
            date_list,
            # 数据靠右显示
            label_opts=opts.LabelOpts(is_show=True, position='right')
        )
        # 横纵坐标翻转
        bar.reversal_axis()
        # 全局配置
        bar.set_global_opts(
            # 标题
            title_opts=opts.TitleOpts(title="豆瓣电影TOP250-第{}年评分TOP10的电影".format(year), pos_left='center'),
            # 横坐标隐藏
            xaxis_opts=opts.AxisOpts(is_show=False, max_=select_film(year)[2], min_=(float(select_film(year)[3]) - 0.1),
                                     split_number=10),
            # 纵坐标
            yaxis_opts=opts.AxisOpts(
                max_=9,
                # 字体大小
                axislabel_opts=opts.LabelOpts(font_size=10),
                # 隐藏坐标轴
                axisline_opts=opts.AxisLineOpts(is_show=False),
                # 隐藏刻度
                axistick_opts=opts.AxisTickOpts(is_show=False)
            )
        )
        # 组合组件
        grid = (
            Grid()
                .add(bar, grid_opts=opts.GridOpts(pos_top='8%', pos_bottom='12%', pos_left='25%'))
        )
        timeline.add(grid, "{}年".format(year))
        timeline.add_schema(is_auto_play=True, play_interval=1000, is_loop_play=False, width='820px', pos_left='60px')
    # 生成HTML
    html = "pages/iframes/score_top.html"
    timeline.render("./templates/" + html)
    return html
## 非完整代码,毕业设计找丹成学长,q746876041

5 最后-毕设帮助

毕设帮助,开题指导,技术解答
🇶746876041

以上是关于毕业设计之 - 题目:基于大数据的电影数据分析可视化系统的主要内容,如果未能解决你的问题,请参考以下文章

毕业设计 - 题目 :基于大数据的疫情数据分析及可视化系统

毕业设计基于大数据的抖音短视频数据分析与可视化 - python 大数据 可视化

毕业设计基于大数据的招聘职业爬取与分析可视化

毕业设计 - 题目: 基于协同过滤的电影推荐系统 - Django 在线电影推荐协同过滤

毕业设计大数据公交数据分析与可视化 - 大数据 python falsk

基于大数据的电影网站项目开发之阶段性总结