豆瓣电影信息爬取与可视化分析

news/2024/7/19 11:25:31 标签: python, 爬虫

目录

一、项目背景

二、代码

三、总结


一、项目背景

(1)利用requests库采集豆瓣网分类排行榜 (“https://movie.douban.com/chart”)中各分类类别前100部电影的相关信息并存储为csv文件。

(2)利用获取的13个分类类别共1300部电影数据,获取电影所有上映国家并保存至csv文件。要求:其中index属性为国家或地区,columns属性为该国家发行电影的电影类型,值标识了各国家发行不同类型电影的数量信息。在表格的行尾和列尾分别加上属性“总计”,值为对应行、列的值加和;然后分别根据表格的index和columns“总计”进行从小到大排序。

(3)基于上述排序后的数据,选取发行电影数量最多的10个国家,选取电影类型最多的5个类型,使用matplotlib方法制作柱状堆叠图。其中横轴显示的国家,纵轴显示的电影数量,图例是各电影类别。

(4)分别获取13个分类类别对应的电影数量前7个国家,其他的用“其他”代替,计算每个分类类别对应的7个国家及“其他”部分的占比。使用matplotlib.pyplot.pie方法直观的显示这13个分类类别对应的国家发行电影数量占比,使用subplot方法进行多子图展示。

(5)计算获得所有电影的相似度(用欧式距离来定义),其中,DataFrame对象的index和columns均为所有的电影名称,值为两个电影的相似度。向每部电影推荐相似都最高的前5部电影。利用循环结构,循环提取每一部电影与其他所有电影的相似度数据,并进行排序,选择相似度最大(距离最近)的5部电影,同时将这5部电影的相似度记录下来。

二、代码

1、导入所需的Python包

python">#导包
import pandas as pd
import requests as rq
from bs4 import BeautifulSoup
import re
import numpy as np
import matplotlib.pyplot as plt
import warnings
warnings.filterwarnings("ignore", category=pd.errors.PerformanceWarning)
warnings.filterwarnings("ignore", category=pd.errors.SettingWithCopyWarning)
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei'] # 指定默认字体:解决plot不能显示中文问题
mpl.rcParams['axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题

各模块功能如下:

pandas:用于数据处理和存储。
requests:用于发送HTTP请求。
BeautifulSoup:用于解析HTML内容。
re:用于正则表达式操作。
numpy:用于数值计算。
matplotlib.pyplot:用于绘图。
warnings:用于过滤警告信息。
pylab:用于设置图形显示的默认配置。

2、爬取豆瓣电影信息

通过requests读取包含电影信息的json,并将其转换为DataFrame。

python">#电影分类
movie_types = ['剧情','喜剧','动作','爱情','科幻','悬疑','惊悚','恐怖','历史','战争','犯罪','奇幻','冒险']
#设置requests headers,应对反爬机制
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0'}

def get_douban_movies():
    '''
    项目内容:
    利用 requests 库采集豆瓣网分类排行榜(“https://movie.douban.com/chart”)
    中各分类类别前 100 部电影的相关信息
    '''
    #豆瓣电影主页
    homepage = 'https://movie.douban.com/chart'
    #爬取主页
    web = rq.get(homepage,headers=headers)
    #设置中文编码
    web.encoding = 'utf-8'
    #解析HTML
    soup = BeautifulSoup(web.text,'lxml')
    #获取分类列表
    urls = [span.a['href'] for span in soup.select('div.types span')]
    require_urls = ['https://movie.douban.com'+u for movie_type in movie_types for u in urls if movie_type in u]
    #获取每个分类的数字编号
    numbers = [re.search(r'type=(\d+)', url).group(1) for url in require_urls]
    #数据存储到data列表
    data = []
    #遍历爬取13个分类
    counts = 0
    for number in numbers:
        url = 'https://movie.douban.com/j/chart/top_list?type={}&interval_id=100%3A90&action=&start=0&limit=100'.format(number)
        response = rq.get(url,headers=headers)
        #获取JSON数据
        data_json = response.json()
        #遍历100个电影
        for i in data_json:
            data.append([i['title'],i['release_date'],i['regions'],
                         i['types'],i['url'],i['actors'],
                         i['actor_count'],i['score'],
                         i['vote_count'],i['types']])
        counts += 1
        print("成功爬取第{}个电影分类".format(counts))
    #将列表data转换为表格,配置列名
    df = pd.DataFrame(data,columns=['title','release_date','regions','types','film_url','actors','actor_count','score','vote_count','fenlei'])
    return df

3、统计各国家地区发行电影数量

python">def get_df_counties(df):
    #打散国家地区
    df = df.explode('regions')
    #创建空表格,后面再填充数据
    df_counties = pd.DataFrame()
    #遍历每一个电影分类
    for t in movie_types:
        df_counties[t] = df['types'].apply(lambda x:1 if t in x else 0)
    df_counties['regions'] = df['regions']
    #汇总
    df_counties = df_counties.groupby('regions').sum()
    df_counties['总计'] = df_counties.sum(axis=1)
    #计算行方向的统计
    count_list = []
    for t in movie_types+['总计']:
        count_list.append(df_counties[t].sum())
    df_counties.loc['总计'] = count_list
    print('统计完成')
    return df_counties

4、绘制各国家地区分类电影堆叠图

python">def draw_bar_diagram(select_data):
    # 创建堆叠柱状图
    ax = select_data.plot.bar(stacked=True, figsize=(10, 6))
    # 添加标题和标签
    plt.title('各国家地区分类电影堆叠图')
    plt.xlabel('国家地区')
    plt.ylabel('电影数目')
    # 显示图形
    plt.savefig('各国家地区分类电影堆叠图.jpg')
    plt.show()

绘制图像如下:

5、绘制各国家地区发行电影数量占比图

python">def draw_pie_diagram(df_counties):
    df_counties = df_counties.drop('总计')
    #处理数据
    df_list = []
    for t in movie_types:
        df_sub = df_counties[t].nlargest(7)
        df_sub.loc['其他'] = df_counties.drop(df_sub.index)[t].sum()
        df_list.append(df_sub)
    # 设置子图布局
    fig, axes = plt.subplots(nrows=4, ncols=4, figsize=(10, 10))
    # 遍历每个电影类型的DataFrame
    for i, df in enumerate(df_list):
        # 将索引转换为整数类型
        #df.index = range(len(df))
        # 计算电影数量占比
        proportions = df / df.sum()
        # 绘制饼图
        ax = axes[i // 4, i % 4]
        ax.pie(proportions, labels=df.index, autopct='%1.1f%%', startangle=90)
        ax.set_title(df.name,fontdict={'fontsize': 20, 'color': 'black'})  # 使用电影类型作为子图标题
    #调整间距
    plt.subplots_adjust(wspace=0.5, hspace=2)
    #隐藏空白子图
    for i in range(len(df_list), 16):
        axes.flatten()[i].axis('off')
    plt.tight_layout()
    plt.savefig('各国家地区发行电影数量占比.jpg')
    # 显示图形
    plt.show()

绘制图像如下:

6、基于近邻规则生成推荐电影信息

python">def get_data_tuijian(df):
    df = df.drop_duplicates(subset='title', keep='first')
    #归一化
    df['score'] = (df['score'] - df['score'].min()) / (df['score'].max() - df['score'].min())
    df['vote_count'] = (df['vote_count'] - df['vote_count'].min()) / (df['vote_count'].max() - df['vote_count'].min())

    data = df[['title','score', 'vote_count']]
    
    #遍历每部电影,计算与其他电影的相似度
    for t in data.title.unique():
        col = data[data.title==t].iloc[0]
        sim_values = []
        for _ ,row in data.iterrows():
            sim_values.append(np.sqrt((row['score']-col['score'])**2+(row['vote_count']-col['vote_count'])**2))
        data[t] = sim_values
        #data[t] = (data[t] - data[t].min()) / (data[t].max() - data[t].min())
    
    #设置索引
    data.index=data.title
    data = data.drop(columns=['title', 'score', 'vote_count'])
    data_tuijian = pd.DataFrame()
    data_tuijian['电影名称'] = data.index
    data_tuijian[['推荐电影1', '推荐电影2', '推荐电影3', '推荐电影4', '推荐电影5',
                  '与电影1相似度', '与电影2相似度', '与电影3相似度', '与电影4相似度', '与电影5相似度']
                ] = None
    #遍历每一部电影,提取每一部电影的前5最相似电影
    for c in data.columns:
        top5 = data[c].sort_values().iloc[1:6].reset_index().values
        for i in range(5):
            data_tuijian.loc[data_tuijian['电影名称']==c,'推荐电影'+str(i+1)] = top5[i][0]
            data_tuijian.loc[data_tuijian['电影名称']==c,'与电影{}相似度'.format(i+1)] = top5[i][1]
    print('推荐信息获取完成')
    return data_tuijian

7、主程序

python">if __name__ == '__main__':
    print('===========项目1、豆瓣电影信息爬取与存储==========')
    df = get_douban_movies()
    df.to_csv('film_info.csv',index=False,encoding='utf-8-sig')
    
    print('===========项目2、国家地区发行各类别电影的可视化分析==========')
    df_counties = get_df_counties(df)
    df_counties.to_csv('df_counties.csv',encoding='utf-8-sig')
    #绘制图表
    select_data = df_counties.sort_values(by='总计',ascending=False).iloc[:11]
    columns = select_data.iloc[0].sort_values(ascending=False).iloc[1:6].index.to_list()
    select_data = select_data[columns].iloc[1:] 
    draw_bar_diagram(select_data)
    draw_pie_diagram(df_counties)
    
    print('===========项目3、基于近邻的电影推荐研究==========')
    df = pd.read_csv('film_info.csv')
    data_tuijian = get_data_tuijian(df)
    data_tuijian.to_csv('data_tuijian.csv',index=False,encoding='utf-8-sig')

三、总结

本项目主要考察的是对requests爬虫、pandas数据处理、matplotlib绘图等Python模块的使用,难度不大。


http://www.niftyadmin.cn/n/5436095.html

相关文章

【数据可视化】Echarts最常用图表

个人主页 : zxctscl 如有转载请先通知 文章目录 1. 前言2. 准备工作3. 柱状图3.1 绘制堆积柱状图3.2 绘制标准条形图3.3 绘制瀑布图 4. 折线图4.1 绘制堆积面积图和堆积折线图4.2 绘制阶梯图 5. 饼图5.1 绘制标准饼图5.2 绘制圆环图5.2 绘制嵌套饼图5.3 绘制南丁格尔…

委托复习【C#】

原因: 主窗体内,新建子窗体后; 主窗体可以调用子窗体的【属性】【方法】等; 但是子窗体内无法调用主窗体的【属性】【方法】。 解决办法: 只有全局的属性和方法,才能被任意调用。 所以,2个窗体相…

环境安装篇 之 Kind 搭建 kubernetes 测试集群

云原生学习路线导航页(持续更新中) 本文是 环境安装 系列文章,介绍 使用Kind工具 快速安装 kubernetes 测试集群的详细步骤 1.Kind简介 Kind 是一个使用 Docker 容器“节点”运行本地 Kubernetes 集群的工具。Kind 主要用于测试kubernetes本…

发布DDD脚手架到Maven仓库,IntelliJ IDEA 配置一下即可使用

这篇文章将帮助粉丝伙伴们更高效地利用小傅哥构建的DDD(领域驱动设计)脚手架,搭建工程项目,增强使用的便捷性。让👬🏻兄弟们直接在 IntelliJ IDEA 配置个在线的链接,就能直接用上这款脚手架&…

带你一文搞懂CNN以及图像识别(Python)

文章目录 一、卷积神经网络简介 二、卷积神经网络的“卷积” 1. 卷积运算的原理 2. 卷积运算的作用 三、卷积神经网络 1. 卷积层(CONV) 2. 池化层(Pooling) 3. 全连接层(FC) 4. 示例:经典CNN的构…

c#——请求一个URL接口

.net 4.6环境下 .net4.6支持异步编程 命名空间&#xff1a; using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; 创建一个异步方法发送请求&#xff1a; public static async Task<string> CallWebAPIAsync(string url, strin…

06 龙芯平台openstack部署搭建-nova-controller部署

一、创建Nova相关数据库、凭据与API端点 1.创建数据库并授权 #nova-controller先决条件 mysql -uroot -ploongson -e “CREATE DATABASE nova_api;” mysql -uroot -ploongson -e “CREATE DATABASE nova;” mysql -uroot -ploongson -e “CREATE DATABASE nova_cell0;” my…

数据可视化-ECharts Html项目实战(3)

在之前的文章中&#xff0c;我们学习了如何创建堆积折线图&#xff0c;饼图以及较难的瀑布图并更改图标标题。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你宝贵的点赞&#xff0c;谢谢。 …