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

news2024/11/24 7:25:02

目录

一、项目背景

二、代码

三、总结


一、项目背景

(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包

#导包
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。

#电影分类
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、统计各国家地区发行电影数量

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、绘制各国家地区分类电影堆叠图

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、绘制各国家地区发行电影数量占比图

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、基于近邻规则生成推荐电影信息

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、主程序

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.coloradmin.cn/o/1523398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#,人工智能,机器学习,聚类算法,训练数据集生成算法、软件与源代码

摘要:本文简述了人工智能的重要分支——机器学习的核心算法之一——聚类算法,并用C#实现了一套完全交互式的、可由用户自由发挥的,适用于聚类算法的训练数据集生成软件——Clustering。用户使用鼠标左键(拖动)即可生成任意形状,任意维度,任意簇数及各种数据范围的训练数…

第十六个实验:FOR循环生成随机数

实验内容: 用For循环生成10个1-2之间的随机数 然后打印出来 实验步骤; 视频: 教学视频

外卖点餐系统 |基于springboot框架+ Mysql+Java+JSP技术+Tomcat的外卖点餐系统 设计与实现(可运行源码+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 骑手功能模块 商家功能模块 管理员功能登录前台功能效果图 用户功能模块 系统功能设…

Dynamo PythonScript 代码速查手册By九哥

你好,这里是 BIM 的乐趣,我是九哥 今天给大家带来的是我的知识工程的第二套知识库,这套知识库不是教程,是一套完整的笔记,里面包含了大量的 Python 代码。 当然这里也没有实现太多的具体逻辑,单纯的是通过 …

可视化软件:第一原理计算/VASP + 结构预测/USPEX

分享一篇 VASPUSPEX 的可视化软件。 感谢论文的原作者! 主要内容 “流行的第一原理仿真代码 Vienna Ab initio Simulation Package (VASP) 和晶体结构预测 (CSP) 包、Universal Structure Predictor: Evolutionary Xtallography (USPEX) 已集成到 GDIS 可视化软件…

项目分享--NO.1

搭建高可用的web集群.部署网站 包含数据库,ceph/nfs,haproxy,keepalived,ansible部署 1,配置ansible管理环境 创建工作目录,编写ansible配置文件,和主机清单文件,yum配置文件 将yum文件到控制机上,然后用模块上传到被管理机器上 #vim 01-upload-repo.yml --- - name: confi…

【开源鸿蒙】为QEMU RISC-V虚拟平台构建OpenHarmony轻量系统

文章目录 一、背景介绍二、准备OpenHarmony源代码三、准备hb命令3.1 安装hb命令3.2 检查hb命令 四、编译RISC-V架构的OpenHarmony轻量系统4.1 设置hb构建目标4.2 启动hb构建过程 五、问题解决5.1 hb set 报错问题解决 六、参考链接 开源鸿蒙坚果派,学习鸿蒙一起来&a…

达梦如何备份以及导入

启动达梦服务 右键选择管理服务器 点击系统管理,点击配置,点击转换 归档配置点击归档 创建文件夹,选择文件夹目录点击确定 命令方式 逻辑备份与还原 逻辑导出(dexp)和逻辑导入(dimp)支持如下四种级别操作: 数据库级(FULL)&#…

【SpringBoot】请求与响应参数 IoC与DI 总结

文章目录 ① —— 请求 ——一、简单参数 RequestParam1.1 参数与形参 命名相同1.2 参数与形参 命名不同 二、实体参数2.1 简单实体对象2.2 复杂实体对象 三、数组集合参数3.1 数组3.2 集合 RequestParam 四、日期参数 DateTimeFormat五、JSON参数 RequestBody六、路径参数 Pat…

Vmware虚拟机使用过程中断电后无法重启处理

背景 今天在用新装的虚拟机进行测试的过程中,忽然笔记本关机了(没插电源线),重启电脑后发现虚拟机提示“正在使用中“,具体如下所示: 解决 在相关虚拟机文件夹内查找以 .lck 结尾的文件,名称一…

如何优化使用Nginx

文章目录 🔊博主介绍🥤本文内容数据压缩负载均衡安装OpenResty或ngx_http_lua_module配置Nginx以启用Lua编写Lua脚本配置upstream块以使用Lua变量测试配置 合并请求1. 确保SSI模块已启用2. 配置Nginx以使用SSI3. 使用SSI指令4. 重新加载或重启Nginx 集成…

【Maven入门篇】(2)IDEA集成Maven环境的具体操作

🎊专栏【Maven入门篇】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【The truth that you leave】 🥰欢迎并且感谢大家指出我的问题 文章目录 🍔配置Maven环境⭐方法一(当前工程&…

选频网络与串联谐振回路

选频网络概述 在高频电子线路中,常以选频网络作为负载。选频网络能选出我们需要的频率分量和滤除不需要的频率分量。 选频网络分类: 1、振荡回路(由L、C组成,也称谐振回路):包括单振荡回路、耦合振荡回路…

Java项目:58 ssm012医院住院管理系统+vue

作者主页:源码空间codegym 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 管理员;首页、个人中心、医护人员管理、科室管理、病人管理、病房管理、病人信息管理、病历管理、医嘱管理、手术安排管理、药品信…

【linux】搜索所有目录和子目录下的包含.git的文件并删除

一、linux命令搜索所有目录和子目录下的包含.git的文件 在Linux系统中,要搜索所有目录和子目录下的包含.git的文件,可以使用find命令。find命令允许指定路径、表达式和操作来查找文件。 以下是使用find命令搜索包含.git的文件的方法: 1. 基…

masm下载和配置

masm下载和配置 1)masm32官网下载地址选择Austrlia 1。 2)解压masm32v11r.zip,点击install.exe安装(一直下一步即可)。 3)安装完成后得到一个masm文件夹。 4)关联DOSBox与masm: 在DOSBox安…

Halcon识别文字案例

识别文字并显示到页面上 read_image (Image, needle1.png) * 打开窗口 dev_open_window (0, 0, 512, 512, black, WindowHandle) dev_display (Image)* 画矩形 gen_rectangle1 (ROI_0, 52.4648, 99.0391, 256.758, 354.063) * 裁剪 reduce_domain (Image, ROI_0, ImageReduced)…

InnoDB B+树索引

没有索引的查找 在一个页中的查找 假设目前表中的记录比较少,所有的记录都可以被存放到一个页中,在查找记录的时候可以根据搜索条件的不同分为两种情况: 以主键为搜索条件 这个查找过程我们已经很熟悉了,可以在页目录中使用二分法…

17双体系Java学习之数组的长度

数组的长度 //获取数组长度 arrays.lengthfor (int i 0; i <nums.length; i) {sum sum nums[i];}System.out.println("总和为&#xff1b;"sum);

【电机芯片】以STM32F103C8T6举例——持续更新

【电机芯片】以STM32F103C8T6举例——持续更新 文章目录 前言一、PWM二、IIC三、UART四、看门狗watchdog五、ADC六、定时器中断七、EEPROM与flash八、时钟九、IAP-Bootloader&#xff0c;APP十、OTA十一、GPIO模式十二、SPI十三、STLINK-DEBUG模式总结 前言 提示&#xff1a;以…