潘粤明的《龙岭迷窟》到底怎么样?我用 Python 得出了一些结论!

对于天下霸唱的鬼吹灯,相信很多小伙伴都知道,它可谓是国内盗墓寻宝系列小说的巅峰之作,最近得知该系列小说的《龙岭迷窟》部分被制作成了网剧,已经于 4 月 1 日开播了,主要演员潘粤明、姜超、张雨绮等都是一些大家比较熟悉的面孔,网剧质量、剧情还原度等到底怎么样呢?我们通过本文来简单了解一下。

我们都知道要了解一件事情是需要用数据说话的,本文数据来源我们还是选择豆瓣的评论区数据吧,先打开该剧豆瓣地址:https://movie.douban.com/subject/30488569/看一下:

获取数据

我们可以看到有1 万多条影评,目前豆瓣对查看影评数据的限制是:未登录最多可以查看 200 条数据,登录用户最多可以查看 500 条数据,我们要做的是通过 Python 爬取豆瓣 500 条影评数据,然后进行数据分析。

首先获取影片列表 URL,具体操作为:点击上图中全部 10806 条,进入影评列表首页,如下图所示:

但我们发现一个问题,该 URL 参数中并没有页码数等信息(实现翻页需要),这个问题我们只需拖动滚动条到底部,然后点击后页按钮即可看到,结果如图所示:

其中start表示起始,limit表示每页数量。再次点击后页可以发现url变成如下所示:

https://movie.douban.com/subject/30488569/comments?start=20&limit=20&sort=new_score&status=P
https://movie.douban.com/subject/30488569/comments?start=40&limit=20&sort=new_score&status=P

通过对比发现start后面的值发生了改变,接着我们看一下如何实现登陆,首先打开登录页,如下图所示:

我们点击:密码登录,然后在输入手机号/邮箱密码输入框处随意输入(不要输入正确的用户名和密码),再按F12键打开开发者工具,最后点击登录豆瓣按钮,结果如图所示:

此时可以看到Request URL(登录所需 URL) 和Form Data项,这两项是我们登录时需要的,当然我们还需User-Agent,点击上面图中所示的Request Headers项即可看到,如图所示:

所需要的东西都找好了,接下来就是具体实现了,豆瓣登录和影评数据爬取的具体实现如下所示:

def spider():
    url = 'https://accounts.douban.com/j/mobile/login/basic'
    headers = {"User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36'}
    # 龙岭迷窟网址,为了动态翻页,start 后加了格式化数字,短评页面有 20 条数据,每页增加 20 条
    url_comment = 'https://movie.douban.com/subject/30488569/comments?start=%d&limit=20&sort=new_score&status=P'
    data = {
        'ck': '',
        'name': '自己的用户名',
        'password': '自己的密码',
        'remember': 'false',
        'ticket': ''
    }
    session = requests.session()
    session.post(url=url, headers=headers, data=data)
    # 初始化 4 个 list 分别存用户名、评星、时间、评论文字
    users = []
    stars = []
    times = []
    content = []
    # 抓取 500 条,每页 20 条,这也是豆瓣给的上限
    for i in range(0, 500, 20):
        # 获取 HTML
        data = session.get(url_comment % i, headers=headers)
        # 状态码 200 表是成功
        print('第', i//20, '页', '状态码:',data.status_code)
        # 暂停 0-1 秒时间,防止 IP 被封
        time.sleep(random.random())
        # 解析 HTML
        selector = etree.HTML(data.text)
        # 用 xpath 获取单页所有评论
        comments = selector.xpath('//div[@class="comment"]')
        # 遍历所有评论,获取详细信息
        for comment in comments:
            # 获取用户名
            user = comment.xpath('.//h3/span[2]/a/text()')[0]
            # 获取评星
            star = comment.xpath('.//h3/span[2]/span[2]/@class')[0][7:8]
            # 获取时间
            date_time = comment.xpath('.//h3/span[2]/span[3]/@title')
            # 有的时间为空,需要判断下
            if len(date_time) != 0:
                date_time = date_time[0]
                date_time = date_time[:10]
            else:
                date_time = None
            # 获取评论文字
            comment_text = comment.xpath('.//p/span/text()')[0].strip()
            # 添加所有信息到列表
            users.append(user)
            stars.append(star)
            times.append(date_time)
            content.append(comment_text)
    # 用字典包装
    comment_dic = {'user': users, 'star': stars, 'time': times, 'comments': content}
    # 转换成 DataFrame 格式
    comment_df = pd.DataFrame(comment_dic)
    # 保存数据
    comment_df.to_csv('data.csv')
    # 将评论单独再保存下来
    comment_df['comments'].to_csv('comment.csv', index=False)

获取的数据在pycharm中展示如下:

分析数据

数据我们已经取到了,接下来我们开始对所获取的数据进行分析。

评论数量

首先,我们来看一下不同时间用户的评论数量,实现代码如下:

csv_data = pd.read_csv('data.csv')
df = pd.DataFrame(csv_data)
df_gp = df.groupby(['time']).size()
values = df_gp.values.tolist()
index = df_gp.index.tolist()
# 设置画布大小
plt.figure(figsize=(8, 5))
# 数据
plt.plot(index, values, label='评论数')
# 设置数字标签
for a, b in zip(index, values):
    plt.text(a, b, b, ha='center', va='bottom', fontsize=13, color='black')
plt.title('评论数量随时间变化折线图')
plt.tick_params(labelsize=10)
plt.ylim(0, 300)
plt.legend(loc='upper right')
plt.show()

效果如下:

人物角色

接着,我们来看所获取的评论数据中,剧中主要角色被提及的次数,实现代码如下:

import matplotlib.pyplot as plt
import pandas as pd
import jieba

# 解决中文显示问题的全局配置
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
# 解决负号显示异常的全局配置
plt.rcParams['axes.unicode_minus'] = False

csv_data = pd.read_csv('data.csv')
df = pd.DataFrame(csv_data)
df_gp = df.groupby(['time']).size()
values = df_gp.values.tolist()
index = df_gp.index.tolist()
# 设置画布大小
plt.figure(figsize=(8, 5))
# 数据
plt.plot(index, values, label='评论数')
# 设置数字标签
for a, b in zip(index, values):
    plt.text(a, b, b, ha='center', va='bottom', fontsize=13, color='black')
plt.title('评论数量随时间变化折线图')
plt.tick_params(labelsize=10)
plt.ylim(0, 300)
plt.legend(loc='upper right')
plt.show()

效果如图:

从图中我们可以看出被提及角色数量的前三甲为:胡八一、王胖子、大金牙,通过角色被提及的次数,我们也可以大致推测出剧中角色的受欢迎程度,角色被提及的次数越多说明其受欢迎的程度应该越高。

评论星级

再接着,我们看一下该剧每天用户的评论星级,星级最高为 5 星,一天中如果有多条评论星级数据,我们则取其平均值,代码实现如下:

import matplotlib.pyplot as plt
import pandas as pd
import jieba
import numpy as np

csv_data = pd.read_csv('data.csv')
df_time = csv_data.groupby(['time']).size()
df_star = csv_data.groupby(['star']).size()
index = df_time.index.tolist()
value = [0] * len(index)
# 生成字典
dic = dict(zip(index, value))
for k, v in dic.items():
    stars = csv_data.loc[csv_data['time'] == str(k), 'star']
    # 平均值
    avg = np.mean(list(map(int, stars.values.tolist())))
    dic[k] = round(avg ,2)
# 设置画布大小
plt.figure(figsize=(8, 5))
# 数据
plt.plot(list(dic.keys()), list(dic.values()), label='星级', color='red', marker='o')
plt.title('评论星级随时间变化折线图')
plt.tick_params(labelsize=10)
plt.ylim(0, 5)
plt.legend(loc='upper right')
plt.show()

效果如下图:

我们从图中可以看出该剧评论星级大致维持在 4 星以上,说明大部分用户对于该剧的质量是比较认可的,评论星级也基本反映出了用户对于该剧的满意度。

词云展示

最后,我们对评论内容进行词云展示,看一下哪些词汇才是评论区的热门词汇,代码实现如下:

from PIL import Image
from wordcloud import WordCloud
import matplotlib.pyplot as plt
import pandas as pd
import jieba
import numpy as np

def jieba_():
    # 打开评论数据文件
    content = open('comment.csv', 'rb').read()
    # jieba 分词
    word_list = jieba.cut(content)
    words = []
    # 过滤掉的词
    remove_words = ['以及', '不会', '一些', '那个', '只有',
                    '不过', '东西', '这个', '所有', '这么',
                    '但是', '全片', '一点', '一部', '一个',
                    '什么', '虽然', '一切', '样子', '一样',
                    '只能', '不是', '一种', '这个', '为了']
    for word in word_list:
        if word not in remove_words:
            words.append(word)
    global word_cloud
    # 用逗号隔开词语
    word_cloud = ','.join(words)

def cloud():
    # 打开词云背景图
    cloud_mask = np.array(Image.open('bg.jpg'))
    # 定义词云的一些属性
    wc = WordCloud(
        # 背景图分割颜色为白色
        background_color='white',
        # 背景图样
        mask=cloud_mask,
        # 显示最大词数
        max_words=100,
         # 显示中文
        font_path='/System/Library/Fonts/Hiragino Sans GB.ttc',
        # 最大尺寸
        max_font_size=80
    )
    global word_cloud
    # 词云函数
    x = wc.generate(word_cloud)
    # 生成词云图片
    image = x.to_image()
    # 展示词云图片
    image.show()
    # 保存词云图片
    wc.to_file('鬼吹灯.png')

效果图:

感兴趣的童鞋们,抓紧时间试一试吧!

展开阅读全文

没有更多推荐了,返回首页

应支付0元
点击重新获取
扫码支付

支付成功即可阅读