Py学习  »  Python

口碑扑街!Python告诉你《完美关系》为何表现不及预期

CDA数据分析师 • 4 年前 • 326 次点击  




 CDA数据分析师 出品  

【导语】:今天我们聊聊国产职场剧《完美关系》,Python技术部分可以直接看第三部分。


Show me data,用数据说话

今天我们聊聊 职场剧《完美关系》

点击下方视频,先睹为快:



最近一连出了好几部职场剧,有孙俪主演讲述房地产行业的《安家》,李易峰主演讲律师的《我在北京等你》,以及佟丽娅、黄轩主演围绕公关行业展开的《完美关系》。

其中,《安家》是翻拍自高分日剧《卖房子的女人》,《我在北京等你》讲的是一名律师奋斗的故事,《完美关系》则是国产职场剧涉及的又一全新行业——公关。

 

那么这三部剧的口碑如何呢?

 

截止到目前为止,《安家》在豆瓣的评分为6.2分,《我在北京等你》豆瓣5.2分,《完美关系》为3.9分。都不是特别好的成绩。

 

《完美关系》播出后更是有公关行业的小伙伴吐槽:我们不想被这么代言啊!

 

那么《完美关系》到底是哪里差强人意呢?今天我们就先聊聊这部《完美关系》

 


01


近年频频扑街的

国产职场剧

 

近年来,推出的国产职场剧还真不少,涉及的行业从地产、互联网、医疗、到翻译、律师等等,几乎形形色色的行业都有。但这些剧的口碑如何呢?

 

先看几部比较热门的:

 

以上这些剧在播出时都频频上热搜,但口碑就差强人意了。分数3.5-5.5不等,连6分及格线都不到。


相关行业的从业者也吐槽,根本没有反应出行业的真实现状,美其名曰职场剧,其实这不是披着行业外衣的偶像剧嘛!

 

进一步汇总国产职场剧的情况可以发现:

图源:DT财经

 

从2008年到2020年3月,共出品64部职场剧,近两年职场题材更有井喷之势,2018年和2019年每年都有13部,数量是2014年的13倍!

 

数量上来了,然后质量就堪忧了。从这些职场剧的豆瓣评分可见,平均分一直在5.5分徘徊。

 


02



披着公关外衣的

《完美关系》

 

那这次瞄准公关行业的《完美关系》能为国产职场剧正名吗?

 

《完美关系》是由安建执导,黄轩、佟丽娅领衔主演,陈数、高露主演的都市职场剧。

 

故事讲的是公关合伙人卫哲、江达琳等人从单枪匹马到并肩作战,积极迎接在公关实战中遇到的压力与困难,互相影响、共同成长的故事。


图源:《完美关系》官方剧照

 

从2月18日首播以来,《完美关系》的收视率越来越高,3月11日《完美关系》凭借6.92%的市场占有率,拿下了收视率排行榜的冠军宝座。

 

 

但同时收获的吐槽和差评也不少,主要集中在:


  • 剧情太浮夸,对公关行业的刻画不真实;

  • 女主的傻白甜人设实在不讨喜;

  • 演员的演技流于表面,难以产生共鸣等等

 


03



《完美关系》豆瓣3.9分

到底冤不冤?


《完美关系》在豆瓣已有60284人进行评分,目前仅为3.9分。那么《完美关系》豆瓣3.9分到底冤不冤呢?

 

我们对《完美关系》豆瓣的影评数据进行了收集整理。


整个数据分析的过程分为三步:


· 获取数据

· 数据预处理

· 数据可视化


以下是具体的步骤和代码实现:


获取数据

1


此次我们选择豆瓣短评的数据作为分析对象。由于豆瓣的限制,非登录状态下最多获取200条数据,登录状态下最多获取500条数据。


为了解决登录的问题,此次我们使用requests的Session方法来让代码自动保存Cookie信息,维持登录和会话保持状态。然后使用Xapth配合正则语句进行数据的提取。


如图所示,本次我们需要获取的主要内容如下:


  • 用户名

  • 用户主页

  • 评论时间

  • 评论星级

  • 短评内容

  • 短评投票数

  • 用户主页(用于获取城市)

  • 评分分布



代码实现:


# 导入所需包
import pandas as pd
import requests
import parsel
import re
import time
from fake_useragent import UserAgent

def login_douban():
    """
    功能:登录豆瓣,维持会话形式
    """

    global s
    # 初始化session
    s = requests.Session()

    # 登录地址
    login_url = 'https://accounts.douban.com/j/mobile/login/basic'
    # 添加headers
    headers = {'user-agent': UserAgent().random}
    # 表单数据
    form_data = {
        'name''你的账号',
        'password''你的密码',
        'remember''false'
    }

    # post登录
    try:
        s.post(login_url, headers=headers, data=form_data)
    except:
        print("登录失败")


def get_one_page(url):
    """
    功能:给定URL地址,获取豆瓣电影一页的短评信息
    :param url: 电影URL地址
    :return: 返回数据框
    """


    # 添加headers
    headers = {'user-agent': UserAgent().random}

    # 发起请求
    try:
        r = s.get(url, headers=headers, timeout=5)
    except:
        time.sleep(3)
        r = s.get(url, headers=headers, timeout=5)

    # 解析网页
    data = parsel.Selector(r.text)

    # 获取用户名
    user_name = [re.findall(r'.*?class="">(.*?).*', i)
                 for i in data.xpath('//span[@class="comment-info"]').extract()]
    # 获取评分
    rating = [re.findall(r'.*?.*', i)
              for i in data.xpath('//span[@class="comment-info"]').extract()]
    # 获取评论时间
    comment_time = [re.findall(r'.*', i)
                    for i in data.xpath('//span[@class="comment-info"]').extract()]
    # 获取短评信息
    comment_info = data.xpath('//span[@class="short"]/text()').extract()
    # 投票次数
    votes_num = data.xpath('//span[@class="comment-vote"]/span/text()').extract()
    # 获取主页URL
    user_url = data.xpath('//div[@class="avatar"]/a/@href').extract()

    # 保存数据
    df_one = pd.DataFrame({
        'user_name': user_name,
        'rating': rating,
        'comment_time': comment_time,
        'comment_info': comment_info,
        'votes_num': votes_num,
        'user_url': user_url
    })

    return df_one

def get_all_page (movie_id, page_num=25):
    """
    功能:获取豆瓣电影25页短评信息
    :param movie_id: 电影ID
    :param page_num: 爬取页面数
    :return: 返回数据框
    """

    df_25 = pd.DataFrame()

    for i in range(page_num):
        # 构造URL
        url = 'https://movie.douban.com/subject/{}/comments?start={}&limit=20&sort=new_score&status=P'.format(movie_id,
                                                                                                              i * 20)
        # 调用函数
        df = get_one_page(url)
        # 循环追加
        df_25 = df_25.append(df, ignore_index=True)
        # 打印进度
        print('我正在获取第{}页的信息'.format(i + 1))
        # 休眠一秒
        time.sleep(1)
    return df_25

if __name__ == '__main__':
    # 先登录豆瓣
    login_douban()
    # 获取完美关系
    df_all = get_all_page(movie_id='30221758')
    print(df_all.shape)


获取的数据以数据框的形式存储,结果如下:



从用户主页的地址可以进一步获取到用户的城市信息,此次共获取500条数据。


数据预处理

2



对于获取的数据,我们需要进行进一步的处理以满足可视化的需求。


  • 推荐星级:转换为1~5分

  • 评论时间:转换为时间类型,并提取日期数据

  • 城市信息:有未填写数据、海外城市、写错的需要进行处理

  • 短评信息:需要进行分词处理


部分关键代码:


# 处理评分列
df['rating'] = [re.sub(r'\[\'\"|\"\'\]' '', i) for i in df['rating']]

# 替换空列表
df['rating'].replace('[]''还行', inplace=True)

# 定义字典
rating_dict = {
    '很差''1星',
    '较差''2星',
    '还行''3星',
    '推荐''4星',
    '力荐''5星'
}

df['rating'] = df['rating'].map(rating_dict)

# 评论信息分词处理
# 合并为一篇
txt = df['comment_info'].str.cat(sep='。')

# 添加关键词
jieba.add_word('黄轩')
jieba.add_word('佟丽娅')
jieba.add_word('男主')
jieba.add_word('女主')
jieba.add_word('跳戏')
jieba.add_word('颜值')
jieba.add_word('吐槽')
jieba.add_word('装逼')
jieba.add_word('国产剧')

# 读入停用词表
stop_words = []
with open('stop_words.txt''r', encoding='utf-8'as f:
    lines = f.readlines()
    for line in lines:
        stop_words.append(line.strip())

# 添加停用词
stop_words.extend(['一部''一拳''一行''10''啊啊啊''一句',
                   'get''哈哈哈哈''哈哈哈''越来越''一步',
                   '一种''样子''几个''第一集' '一点',
                   '第一''没见''一集''第一次''两个',
                   '二代''真的''2020''令人'])

# 评论字段分词处理
word_num = jieba.analyse.extract_tags(txt,
                                      topK=100,
                                      withWeight=True,
                                      allowPOS=())

# 去停用词
word_num_selected = []

for i in word_num:
    if i[0not in stop_words:
        word_num_selected.append(i)

key_words = pd.DataFrame(word_num_selected, columns=['words','num'])


数据可视化

3


我们使用pyecharts进行数据可视化分析,安装命令:pip install pyecharts。分析结果如下:


总体评分分布


有41.6%的人都给了1星,其次28.2%的人给了5星。15.4%的人给了2星。由此可见本剧的两极分化特别严重,有些人特别喜欢给到了5星好评,同时觉得拍的很烂的也有不少。


代码实现:

 

score_perc = df['rating'].value_counts() / df['rating'].value_counts().sum()
score_perc = np.round(score_perc*100 ,2)
print(score_perc)

# 绘制饼图
from pyecharts.charts import Pie
from pyecharts import options as opts

pie1 = Pie(init_opts=opts.InitOpts(width='1350px', height='750px'))
pie1.add("",
         [*zip(score_perc.index, score_perc.values)],
         radius=["35%","70%"])
pie1.set_global_opts(title_opts=opts.TitleOpts(title='总体评分分布'),
                     legend_opts=opts.LegendOpts(orient="vertical", pos_top="15%", pos_left="2%"),
                     toolbox_opts=opts.ToolboxOpts())
pie1.set_series_opts(label_opts=opts.LabelOpts(formatter="{c}%"))
pie1.set_colors(['#D7655A''#FFAF34''#3B7BA9''#EF9050''#6FB27C'])
pie1.render()


评分热度时间走势


评分热度主要集中在2月18日,也就是《完美关系》首播的那天,其次热度不断下降。


代码实现:


df['comment_time'] = pd.to_datetime(df['comment_time'])
df['comment_date'] = df['comment_time'].dt.date
comment_num = df['comment_date'].value_counts().sort_index()

# 折线图
from pyecharts.charts import Line

line1 = Line(init_opts=opts.InitOpts(width='1350px', height='750px'))
line1.add_xaxis(comment_num.index.tolist())
line1.add_yaxis('评论热度', comment_num.values.tolist(),
                areastyle_opts=opts.AreaStyleOpts(opacity=0.5),
                label_opts=opts.LabelOpts(is_show=False))
line1.set_global_opts(title_opts=opts.TitleOpts(title='时间走势图'),
                      toolbox_opts=opts.ToolboxOpts(),
                      visualmap_opts=opts.VisualMapOpts(max_=200))
line1.render()


评论用户城市分布




观看和评分人群主要集中在北上广三地,其次是江苏、四川等地。



代码实现:

# 国内城市top10
city_top10 = df['city_dealed'].value_counts()[:12]
city_top10.drop('国外', inplace=True)
city_top10.drop('未填写', inplace=True)

# 条形图
from pyecharts.charts import Bar

bar1 = Bar(init_opts=opts.InitOpts(width='1350px', height='750px'))
bar1.add_xaxis(city_top10.index.tolist())
bar1.add_yaxis("城市", city_top10.values.tolist())
bar1.set_global_opts(title_opts=opts.TitleOpts(title="评论者Top10城市分布"),
                     visualmap_opts=opts.VisualMapOpts(max_=50),
                     toolbox_opts=opts.ToolboxOpts())
bar1.render()


city_num = df['city_dealed'].value_counts()
city_num.drop('国外', inplace=True)
city_num.drop('未填写', inplace=True)

from pyecharts.charts import Map

# 地图
map1 = Map(init_opts=opts.InitOpts(width='1350px', height='750px'))
map1.add("", [list(z) for z in zip(city_num.index.tolist(), city_num.values.tolist())],
         maptype='china')
map1.set_global_opts(title_opts=opts.TitleOpts(title='评论者国内城市分布'),
                     visualmap_opts=opts.VisualMapOpts(max_=50),
                     toolbox_opts=opts.ToolboxOpts())
map1.render()


评论词云


而在词云方面讨论最多的就是黄轩佟丽娅两大主演了。


其次关于女配陈数的讨论也很多,无论是陈数这次强大的职场新女性人设,还是惊艳干练的职场穿搭都是很吸睛的。



然后对演技」和剧情上的吐槽也不少。评价中油腻尴尬狗血等负面词频频出现。


代码实现: 

# 词云图
from pyecharts.charts import WordCloud
from pyecharts.globals import SymbolType

word1 = WordCloud(init_opts=opts.InitOpts(width='1350px', height='750px'))
word1.add("", [*zip(key_words.words, key_words.num)],
          word_size_range=[20200],
          shape=SymbolType.DIAMOND)
word1.set_global_opts(title_opts=opts.TitleOpts('完美关系豆瓣短评词云图'),
                      toolbox_opts=opts.ToolboxOpts())
word1.render()


那么《完美关系》你怎么看呢?


关注CDA数据分析师公众号
回复关键字“完美关系” 
获取 详细数据代码

CDA数据分析师 

作者:Mika

数据:真达  

后期:泽龙  设计:一凡  

本文出品:CDA数据分析师(ID: cdacdacda)


📚推荐阅读 READ MORE

(点击下方图片阅读)

全国多地病例0新增,教你用Python画出当下最火的疫情直观图


 

📌CDA课程咨询


喜欢本篇内容请点个“在看”哦!❤️

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/56271
 
326 次点击