《中国医生》值不值得看?Python爬取4w+观影数据告诉你答案

Python 专栏收录该内容
27 篇文章 58 订阅

前言

最近一部根据真实事件改编的《中国医生》正在火热上映,感动了无数观众,更获钟南山院士高度评价:“真正体现了中国医生的良心、责任、决心、行动!

影片以金银潭医院为核心故事背景,将抗疫中各地发生的真人真事浓缩凝练,全景式还原记录了波澜壮阔、艰苦卓绝的抗疫斗争。

网友也对《中国医生》原型展开热烈讨论,关于《中国医生》的话题在多个平台登上热搜,今天我们就通过抓取近4万条评论数据,看看电影观众们对这部电影的评价究竟如何?

在这里插入图片描述

一、核心功能设计

总体来说,我们需要先从猫眼电影爬取《中国医生》的影评数据,并将这些数据进行可视化分析展示。

拆解需求,大致可以整理出我们需要分为以下几步完成:

  1. 通过爬虫获取猫眼APP的评论数据,包括用户名,用户城市,评论内容,星级打分,评论时间等。
  2. 对获取的评论数据进行预处理,获取用户对于电影的星级评分,并通过饼图进行可视化显示。
  3. 根据评论数据中的城市进行观影用户区域分布可视化。
  4. 对影评内容进行词云绘制。

二、实现步骤

1. 爬取数据

首先我们需要获取猫眼APP上的评论数据,通过分析发现,猫眼APP的评论数据接口为:https://m.maoyan.com/mmdb/comments/movie/1337700.json_v_=yes&offset=0&startTime=2021-07-14%2022%3A25%3A03。

根据对数据分析,返回的json格式数据,可以发现:

  • 1337700就是代表《中国医生》电影的id
  • offset表示偏移量
  • startTime表示获取评论的起始时间
  • cmts表示评论,每次获取15条,offset偏移量是指每次获取评论时的起始索引,向后取15条
  • cmts中有我们需要的用户id、用户名、城市名、评论内容、评论星级分数、评论时间等信息
    在这里插入图片描述

网页结构我们上面已经分析好了,那么我们就可以来动手爬取我们所需要的数据了。获取到所有的数据资源之后,可以把这些数据保存下来。

获取数据:

# 获取数据,根据url获取
def get_data(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.123 Safari/537.36',
           }
    response = requests.get(url=url, headers=headers)
    html_data = response.text
    # print(html_data)
    return html_data

在这里插入图片描述

处理数据:

# 处理数据
def parse_data(html):
    data = json.loads(html)['cmts']  # 将str转换为json
    comments = []
    for item in data:
        comment = {
            'id': item['id'],
            'nickName': item['nickName'],
            'cityName': item['cityName'] if 'cityName' in item else '',  # 处理cityName不存在的情况
            'content': item['content'].replace('\n', ' ', 10),  # 处理评论内容换行的情况
            'score': item['score'],
            'startTime': item['startTime']
        }
        comments.append(comment)
    return comments

存储数据:

# 存储数据,存储到文本文件
def save_to_data():
    start_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 获取当前时间,从当前时间向前获取
    end_time = '2021-07-09 00:00:00'
    while start_time > end_time:
        url = 'https://m.maoyan.com/mmdb/comments/movie/1337700.json?_v_=yes&offset=0&startTime=' + start_time.replace(' ', '%20')
        html = None

        try:
            html = get_data(url)
        except Exception as e:
            # 当请求过于频繁时,服务器会拒绝连接,实际上是服务器的反爬虫策略
            time.sleep(0.5)
            html = get_data(url)
        else:
            time.sleep(0.1)

        comments = parse_data(html)
        print(comments)
        start_time = comments[14]['startTime']  # 获得末尾评论的时间
        start_time = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S') + timedelta(seconds=-1)  # 转换为datetime类型,减1秒,避免获取到重复数据
        start_time = datetime.strftime(start_time, '%Y-%m-%d %H:%M:%S')  # 转换为str

        for item in comments:
            with open('中国医生.txt', 'a', encoding='utf-8') as f:
                f.write(str(item['id'])+','+item['nickName'] + ',' + item['cityName'] + ',' + item['content'] + ',' + str(item['score'])+ ',' + item['startTime'] + '\n')

这样我们就可以把需要用到的观影用户数据存储下来了,效果如下:

在这里插入图片描述
数据获取存储之后,接下来我们就需要对数据进行可视化显示。 这里使用的是pyecharts,是一个用于生成Echarts图表的类库,便于在Python中根据数据生成可视化的图表。

之前博主有写过一篇关于pyecharts的文章,里面很详细的介绍了各类图表的使用方法和案例,不会的可以先去学习下pyecharts相关的内容。【一文学会炫酷图表利器pyecharts】

2. 星级评分

我们根据上面获取的观影数据,其中有一个score属性代表电影分数,我们需要读取用户的评分进行一星至五星格式转换。

# 获取评论中所有评分
rates = []
with open('中国医生.txt', mode='r', encoding='utf-8') as f:
    rows = f.readlines()
    for row in rows:
        try:
            rates.append(row.split(',')[4])
        except:
            pass

# print(rates)

# 定义电影评分星级  统计各星级评分数量
attr = ['五星', '四星', '三星', '二星', '一星']
value = [
    rates.count('5.0') + rates.count('4.5'),
    rates.count('4.0') + rates.count('3.5'),
    rates.count('3.0') + rates.count('2.5'),
    rates.count('2.0') + rates.count('1.5'),
    rates.count('1.0') + rates.count('0.5')
]
# print(value)

拿到对应的星级数据之后,我们可以绘制饼状图查看电影评分比例数据。

pie = (
    Pie()
    .add("", [list(z) for z in zip(attr, value)])
    .set_global_opts(title_opts=opts.TitleOpts(title="《中国医生》评分比例饼图"))
    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{d}%"))
)
pie.render('评分.html')

效果如下:
在这里插入图片描述
从图中可以看出,五星比例接近89.5%,四星比例为6.5%,两者合计高达96%,可见《中国医生》电影的口碑还是相当不错的。

3. 观影用户分布

我们还可以根据存储的数据中cityName获取观影用户的地点分布情况。

获取评论中所有城市:

# 获取评论中所有城市
cities = []
with open('./中国医生.txt', mode='r', encoding='utf-8') as f:
    rows = f.readlines()
    for row in rows:
        try:
            city = row.split(',')[2]
        except IndexError:
            pass
        if city != '':  # 去掉城市名为空的值
            cities.append(city)

统计每个城市出现的次数:

# 统计每个城市出现的次数
data = []
value = []
attr = []
for city in set(cities):
    data.append((city, cities.count(city)))
#数据超过94个时会报错,应该是有限制吧
data = Counter(cities).most_common(93)
value = [city[1] for city in data]
#确定最小值和最大值
max2 = value[0]
min2 = value[-1]
#将数值调整为可分段显示
if (max2-min2)%5!=0:
    max2 = max2 + (5-(max2-min2)%5)

# 使用Counter类统计出现的次数,并转换为元组列表
data_top25 = Counter(cities).most_common(25)
attr = [city[0] for city in data_top25]
value = [city[1] for city in data_top25]
max1 = value[0]
min1 = value[-1]

绘制观影用户Top25分布:

def bar_base():
        c = (
            Bar()
            .add_xaxis(attr)
            #category_gap是指单系柱距离
            .add_yaxis("", value,category_gap="15%")
            .set_series_opts(label_opts=opts.LabelOpts(is_show=True))
            .set_global_opts(
                title_opts=opts.TitleOpts(
                    title="《中国医生》观影用户排行TOP25", subtitle="数据来源:猫眼 -- Dragon少年",pos_left="400px"),
                visualmap_opts=opts.VisualMapOpts(min_=min1, max_=max1),
                #显示所有x值,不设置会自动隐藏一些x值
                xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(interval=0))
            )
        )
        return c

效果如下:

在这里插入图片描述

观影用户地区分布:

def geo_base():
        c = (
            Geo()
            .add_schema(
                maptype="china"
                )
            .add("", [list(x) for x in data])
            .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
            .set_global_opts(
                visualmap_opts=opts.VisualMapOpts(is_piecewise=True,min_=min2, max_=max2),
                title_opts=opts.TitleOpts(title="《中国医生》观影用户分布", subtitle="数据来源:猫眼 -- Dragon少年",pos_left="300px"),
            )
        )
        return c

效果如下:

在这里插入图片描述
电影消费是城市消费的一部分,从某种角度来看,可以作为考察一个城市购买力的指标。可以看出这些观影用户较多的城市在近年的GDP排行中也大多数居上游,消费水平较高。

4. 影评词云图

首先我们需要准备工作,安装jieba用来进行评论内容分词。jieba是一个基于Python的分词库,完美支持中文分词,功能强大。

还要安装wordcloud,一个基于Python的词云生成类库,可以生成词云图。

pip install jieba
pip install wordcloud

pyecharts v0.3.2以后,pyecharts 将不再自带地图 js 文件。如用户需要用到地图图表,可自行安装对应的地图文件包。

# 安装地图文件包
pip install echarts-china-provinces-pypkg # 中国省、市、县、区地图
pip install echarts-china-cities-pypkg
pip install echarts-china-counties-pypkg
pip install echarts-china-misc-pypkg 
pip install echarts-countries-pypkg # 全球国家地图
pip install echarts-united-kingdom-pypkg

准备工作完成之后,我们就可以根据存储的电影评论数据,绘制词云图了。

获取所有评论:

# 获取所有评论
comments = []
with open('中国医生.txt', mode='r', encoding='utf-8') as f:
    rows = f.readlines()
    for row in rows:
        try:
            comment = row.split(',')[3]
            if comment != '':
                comments.append(comment)
        except:
            pass

设置分词、屏蔽词:

# 设置分词
comment_after_split = jieba.cut(str(comments), cut_all=False)  # 非全模式分词,cut_all=false
words = ' '.join(comment_after_split)  # 以空格进行拼接
# print(words)

# 设置屏蔽词
stopwords = STOPWORDS.copy()
stopwords.add('电影')
stopwords.add('我')
stopwords.add('我们')
stopwords.add('的')
stopwords.add('是')
stopwords.add('了')
stopwords.add('没有')
stopwords.add('什么')
stopwords.add('有点')
stopwords.add('不是')
stopwords.add('真的')
stopwords.add('感觉')
stopwords.add('觉得')
stopwords.add('还是')
stopwords.add('但是')

绘制词云图:

# 导入背景图
bg_image = plt.imread('bg.jpg')

# 设置词云参数,参数分别表示:画布宽高、背景颜色、背景图形状、字体、屏蔽词、最大词的字体大小
wc = WordCloud(width=1024, height=768, background_color='white', mask=bg_image, font_path='STKAITI.TTF',
               stopwords=stopwords, max_font_size=400, random_state=50)
# 将分词后数据传入云图
wc.generate_from_text(words)
plt.imshow(wc)
plt.axis('off')  # 不显示坐标轴
plt.show()
# 保存结果到本地
wc.to_file('词云图.jpg')

效果如下:

在这里插入图片描述
至此,《中国医生》电影分析可视化就完成啦~

从分析可以看出,电影整体口碑还是很不错的,故事中有好多泪点,展现出了中国医生的敬业、中国医生的力量,中国医生的责任,身为中国人,身边有一群这样的天使,感到无比的骄傲!为中国医生点赞!

今天我们就到这里,明天继续努力!
在这里插入图片描述
若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。

创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!

Dragon少年 | 文

如果本篇博客有任何错误,请批评指教,不胜感激 !

相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值