首页 > 其他分享 >爬取豆瓣影评数据可视化分析

爬取豆瓣影评数据可视化分析

时间:2022-12-13 00:46:19浏览次数:38  
标签:plt df 爬取 range 豆瓣 可视化 time counts data

目的:利用python爬虫爬取豆瓣电影的短评等数据,完成数据的清洗及可视化。

步骤:1、抓取数据;

   2、数据处理;

   3、数据可视化。

本文会以《楚门的世界》为例,通过爬取短评、评分、时间等数据来进行探索。

首先导入模块

import requests
import re,time
import pandas as pd
from bs4 import BeautifulSoup
import csv
import codecs  # 保存数据
import matplotlib.pyplot as plt
from matplotlib import font_manager
from pylab import mpl
from wordcloud import WordCloud  # 词云
import jieba  # 分词
import numpy,collections  # 词频统计

1、数据的爬取:

def getdata():
    header = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
              "cookie": "_uuid=DB17FC3E-C33B-0402-FEC8-6D5F54FFD75826400infoc; buvid3=524A488F-FA38-4505-A9FD-80539B19E3FB184978infoc; sid=a2zoyf7s; buvid_fp=524A488F-FA38-4505-A9FD-80539B19E3FB184978infoc; DedeUserID=650586683; DedeUserID__ckMd5=673346effe04fe44; SESSDATA=dc4b2c16%2C1628474903%2Cc95da*21; bili_jct=f92980128fe4681476212c6cfe3d0ff7; CURRENT_FNVAL=80; blackside_state=1; rpdid=|(J|)JR|||Rm0J uYukmkkmJk; fingerprint3=dc6c77bb0dfdccdd39bc9efbb780630d; fingerprint=f29725bb59f7984374f945e2ebddc362; buvid_fp_plain=524A488F-FA38-4505-A9FD-80539B19E3FB184978infoc; fingerprint_s=0a7abb581b9ea03451e614a51a3d4b2b; LIVE_BUVID=AUTO8416133069733130; bp_video_offset_650586683=491829482594004200; bsource=search_baidu; PVID=1; bfe_id=1e33d9ad1cb29251013800c68af42315"}
    original_url = 'https://movie.douban.com/subject/1292064/comments?start='
    original_url2 = '&limit=20&status=P&sort=new_score'
    item = {}
    temp_list = []
    # 爬取豆瓣影评信息,返回response, 并进行解析
    for page in range(30):
        comments = ""
        url = original_url+ str(page*20) +original_url2
        # print(url)
        resp = requests.get(url, headers=header)
        soup = BeautifulSoup(resp.text, 'html.parser')
        # 返回的是class为“main review-item”的所有<div>标签
        p_list = soup.find_all('div', {'class': 'comment-item'})
        for p_div in p_list:
            # id
            id = p_div.get('data-cid')
            # 短评内容
            content = p_div.find('span', {'class': 'short'}).text
            # 发布时间
            pub_time = p_div.find('span', {'class': 'comment-time'}).text.replace('\n','').strip(' ')
            # 评分(5力荐 4推荐 3还行 2较差 1很差)
            rating = p_div.find('span', {'class': 'rating'})
            # 没有评分的暂空
            if rating:
                rating = rating.get('title')
            else: rating = ""
            item = {
                'id':id,
                "pub_time": pub_time,
                "rating": rating,
                "content": content,
            }
            temp_list.append(item)
        time.sleep(1)
    # print(temp_list)
    # 解决保存乱码的问题
    with open("{}.csv".format('ceshi'), "ab+") as file:
        file.write(codecs.BOM_UTF8)
    # 保存数据
    with open('{}.csv'.format('ceshi'), 'a',newline = "",encoding='utf-8') as file:
        writer = csv.writer(file)
        for i in temp_list:
            info = [i['id'],i['pub_time'],i['rating'],i['content']]
            writer.writerow(info)
    resp.close()
    # DataFrame注意大小写
    df = pd.DataFrame(temp_list)
    return df

2、数据处理

爬取到的数据展示:

def process():
    df = getdata()
    # 没有评分的视为 放弃
    df["rating"].fillna("放弃", inplace = True)
    # 将时间格式改为日期
    df['pub_time'] = pd.to_datetime(df['pub_time'])
    return df

3、数据可视化

(1)时间分布图

def visual_1():
    #时间分布图
    data = process()
    # 指定多个时间区间[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24]
    time_range = list(range(0,25,2))
    # 获取评论时间中的hour  .dt.hour
    frame = data['pub_time'].dt.hour
    # 把一组数据分割成离散的区间,并获取每个区间的评论数 pd.cut()
    # 第一个参数:被切分的数据,必须是一维的
    # 第二个参数:bins:被切割后的区间
    # 第三个参数:right:表示是否包含区间右部,默认为True
    # .value_counts() 给值计数
    time_range_counts = pd.cut(frame, bins=time_range, right=False).value_counts()
    # print('time_range_counts',time_range_counts)
    # print('time_range_counts.index',time_range_counts.index)
    # print('time_range_counts.values',time_range_counts.values)

    # 创建一个画布,并指定宽、高
    plt.figure(figsize=(10, 5))
    # 字体
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    # 绘制柱状图
    plt.bar(range(len(time_range_counts.index)), time_range_counts.values,
            color=['lightskyblue'])
    # 配置坐标及对应标签
    plt.xticks(range(len(time_range_counts.index)), time_range_counts.index)
    # 设置横轴标签
    plt.xlabel('时间区间')
    # 设置纵轴标签
    plt.ylabel('评论人数')
    # 保存图形
    plt.savefig('柱状图.jpg')
    # 显示图形
    plt.show()

(2)评分图

def visual_2():
    # 评分饼图
    data = process()
    # 字体
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    # 按照评分进行聚合
    grouped = data['id'].groupby(data['rating'])
    grouped_count = grouped.count()
    print(grouped_count)

    # 图片大小
    plt.figure(figsize=(3, 3), dpi=200)

    # 饼图样式
    plt.pie(grouped_count.values, labels=grouped_count.index, autopct='%1.1f%%',pctdistance=0.9,
             radius=1, counterclock=False, textprops=dict(size=5))
    plt.savefig('评分图.jpg')
    plt.show()

(3)词云图

def visual_3():
    # 词云图
    data = process()
    comments = ''

    for k in range(len(data['content'])):
        comments = comments + (str(data['content'][k])).strip()
    # \u4e00、\u9fa5表示中文编码的开始和结束的两个值
    filterdata = re.findall('[\u4e00-\u9fa5]', comments)
    cleaned_data = ''.join(filterdata)
    # print(cleaned_data)  
    # 文本分词
    segment = jieba.lcut(cleaned_data)
    words_df = pd.DataFrame({'segment': segment})

    # 去停用词
    stopwords = pd.read_csv("stopwords.txt", index_col=False, quoting=3, sep="\t", names=['stopword'],
                            encoding='utf-8')  # quoting=3全不引用
    words_df = words_df[~words_df.segment.isin(stopwords.stopword)]

    # 词频统计
    word_counts = collections.Counter(words_df['segment'])
    # 获取前20最高频的词检查
    word_counts_top20 = word_counts.most_common(20)
    print(word_counts_top20)
    # 绘制词云图
    wc = WordCloud(font_path='C:/Windows/Fonts/simkai.ttf',  # 字体
                   background_color='white',  # 背景颜色
                   width=1200,
                   height=600,
                   max_words=200,  # 最大词数
                   max_font_size=200,  # 字体大小
                   random_state=1234)  # 设置多少种随机的配色方案
    fig = wc.generate_from_frequencies(word_counts)
    plt.figure(figsize=(12, 6))
    plt.imshow(fig)
    plt.axis('off')
    plt.savefig('词云图.jpg', dpi=600)
    plt.show()

4、数据可视化分析

可以看到:

20:00~24:00时间段评论人数最多,4:00~6:00时间段人数最少。

由此可见,大家都是喜欢选择晚上看电影,而相对不喜欢在凌晨看电影。

 

可以看到:“力荐”“推荐”的评分人数比例远远高于“放弃”“较差”“还行”,

由此可见,大家都很喜欢《楚门的世界》这部电影,评分很高,推荐观看。

此为词云图。

 

标签:plt,df,爬取,range,豆瓣,可视化,time,counts,data
From: https://www.cnblogs.com/juanmei/p/16977475.html

相关文章