news 2026/8/19 10:16:12

Python 爬虫实战:豆瓣高分电影可视化分析(四维爬虫 + 11 张图,附完整源码)4部分

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 爬虫实战:豆瓣高分电影可视化分析(四维爬虫 + 11 张图,附完整源码)4部分

一、可视化实现(真实源码 + 运行输出)

可视化代码集中在数据可视化处理.ipynb,本文只挑核心片段贴出来,图片全部是程序实际运行输出的 PNG(dpi=300)。

1.1 环境配置:中文字体是第一个坑

import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib as mpl import seaborn as sns from matplotlib.font_manager import FontProperties # ===================== 中文字体配置 ===================== font_path = "C:/Windows/Fonts/simhei.ttf" font_prop = FontProperties(fname=font_path) mpl.rcParams["font.family"] = ["SimHei", "Microsoft YaHei"] mpl.rcParams["axes.unicode_minus"] = False plt.style.use("seaborn-v0_8-whitegrid") ===================== 全局配置 ===================== SAVE_PATH = r"...\可视化处理\可视化图片" def save_fig(fig_name): plt.tight_layout() plt.savefig(f"{SAVE_PATH}\{fig_name}.png", dpi=300, bbox_inches="tight") plt.close()

踩坑提醒:Windows 下 Matplotlib 默认字体不含中文,不设置的话标题和图例全是方框;axes.unicode_minus = False是为了让负号正常显示。

1.2 数据加载与预处理

df_total = pd.read_csv("...\清洗后数据集\douban_total_clean.csv") df_top250 = pd.read_csv("...\清洗后数据集\douban_top250_clean.csv") 1. 类型拆分:一部电影可能有多个类型(用空格分隔) df_type_expand = df_total.dropna(subset=["类型"]).copy() df_type_expand["类型"] = df_type_expand["类型"].str.split(" ") type_expand = df_type_expand.explode("类型") 2. 年代标签映射为大致年份 year_map = { "更早": 1950, "60年代": 1965, "70年代": 1975, "80年代": 1985, "90年代": 1995, "2000年代": 2005, "2010年代": 2015, "2019": 2019, "2020": 2020, "2021": 2021, "2022": 2022 } df_total["上映年份_映射"] = df_total["年代标签"].map(year_map).fillna(2000).astype(int) 3. 四大社会时期划分 def get_period(year): if 1947 <= year <= 1991: return "冷战时期" elif 2007 <= year <= 2009 or year == 2020: return "经济危机时期" elif 2020 <= year <= 2022: return "疫情时期" elif (2001 <= year <= 2007) or (2010 <= year <= 2019): return "世界经济上行时期" else: return "其他时期" df_total["社会时期"] = df_total["上映年份_映射"].apply(get_period) df_period = df_total[df_total["社会时期"] != "其他时期"].copy()

1.3 总数据集五连图:高分电影的普遍规律

① 年代数量与评分趋势(双轴图)

time_analysis = df_total.groupby("年代标签").agg( 电影数量=("评分", "count"), 平均评分=("评分", "mean") ).reset_index() fig, ax1 = plt.subplots(figsize=(14, 6)) ax1.bar(time_analysis["年代标签"], time_analysis["电影数量"], color="#4ECDC4", alpha=0.8) ax1.set_ylabel("电影数量") ax2 = ax1.twinx() ax2.plot(time_analysis["年代标签"], time_analysis["平均评分"], color="#FF6B6B", marker="o", linewidth=3) ax2.set_ylabel("平均评分") plt.title("高分电影年代数量与评分趋势") save_fig("01_总数据集_年代趋势分析")

② 地区占比 + 评分对比

region_count = df_total["地区"].value_counts() region_score = df_total.groupby("地区")["评分"].mean().sort_values(ascending=False) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6)) ax1.pie(region_count, labels=region_count.index, autopct="%.1f%%", colors=["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#FECA57"]) ax1.set_title("高分电影地区占比") sns.barplot(x=region_score.index, y=region_score.values, ax=ax2) ax2.set_title("各地区平均评分对比") save_fig("02_总数据集_地区分布分析")

③ TOP15 电影类型分布

type_count = type_expand["类型"].value_counts().head(15) plt.figure(figsize=(12, 8)) sns.barplot(y=type_count.index, x=type_count.values, palette="viridis") plt.title("高分电影TOP15类型分布") for i, v in enumerate(type_count.values): plt.text(v + 5, i, str(v), va="center") save_fig("03_总数据集_类型分布分析")

④ 评分分布

plt.figure(figsize=(10, 6)) sns.histplot(df_total["评分"], bins=15, kde=True, color="#5470C6") plt.title("高分电影评分分布") plt.xlabel("豆瓣评分") plt.ylabel("电影数量") save_fig("04_总数据集_评分分布分析")

⑤ 四大社会时期:类型偏好 + 评分对比

# 先按时期拆类型,统计各时期 TOP5 类型 df_period_type = df_period.dropna(subset=["类型"]).copy() df_period_type["类型"] = df_period_type["类型"].str.split(" ") df_period_type = df_period_type.explode("类型") period_type_list = [] for period in df_period_type["社会时期"].unique(): subset = df_period_type[df_period_type["社会时期"] == period] for t, c in subset["类型"].value_counts().head(5).items(): period_type_list.append({"社会时期": period, "类型": t, "电影数量": c}) period_type_top5 = pd.DataFrame(period_type_list) plt.figure(figsize=(16, 8)) sns.barplot(data=period_type_top5, x="类型", y="电影数量", hue="社会时期", palette="Set2") plt.title("四大社会经济时期高分电影TOP5类型对比") save_fig("05_总数据集_四大时期类型分析") 各时期平均评分 period_score = df_period.groupby("社会时期")["评分"].mean().sort_values(ascending=False) plt.figure(figsize=(10, 6)) sns.barplot(x=period_score.index, y=period_score.values, palette="coolwarm") plt.title("四大社会经济时期高分电影平均评分对比") save_fig("06_总数据集_四大时期评分分析")

结论(这是全篇最让我意外的部分)

时期观众偏好平均评分
冷战时期(1947–1991)剧情、犯罪、战争、科幻(军备竞赛、太空竞赛的时代写照)8.92
经济危机时期(2007–2009、2020)喜剧、温馨、治愈、动画(逃避现实、寻求放松)8.65
疫情时期(2020–2022)剧情、喜剧、温情、悬疑(居家观影,流媒体爆发)8.58
经济上行时期(2001–2007、2010–2019)科幻、动作、冒险、动画齐发力(工业化 + 多元化)8.73

一句话总结:社会越紧张,观众越想看治愈的内容;社会越繁荣,类型越百花齐放。

7.4 Top250 三连图:顶级口碑电影是怎么炼成的

① 高频导演平均评分

director_score = df_top250.groupby("导演")["评分"].agg( ["count", "mean"] ).sort_values(by="count", ascending=False).head(10) plt.figure(figsize=(12, 6)) sns.barplot(x=director_score.index, y=director_score["mean"], palette="coolwarm") plt.title("Top250高频导演平均评分对比") plt.xticks(rotation=45) plt.ylabel("平均评分") save_fig("07_Top250_导演分析")

② 主演与评分关联(Plotly 交互散点图)

import plotly.express as px fig = px.scatter(df_top250, x="主演", y="评分", hover_name="电影名称", title="Top250主演-评分关联") fig.update_layout(height=500, xaxis={"tickangle": 45}) fig.show()

③ 类型、地区、评分分布三件套

# Top250 类型分布 top250_type = df_top250.dropna(subset=["类型"]).copy() top250_type["类型"] = top250_type["类型"].str.split(" ") top250_type_count = top250_type.explode("类型")["类型"].value_counts().head(10) plt.figure(figsize=(10, 6)) sns.barplot(x=top250_type_count.index, y=top250_type_count.values) plt.title("Top250电影TOP10类型分布") save_fig("09_Top250_类型特征分析") Top250 地区占比 + 评分 top250_region = df_top250["地区"].value_counts() top250_region_score = df_top250.groupby("地区")["评分"].mean() fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6)) ax1.pie(top250_region, labels=top250_region.index, autopct="%.1f%%") ax1.set_title("Top250电影地区占比") sns.barplot(x=top250_region_score.index, y=top250_region_score.values, ax=ax2) ax2.set_title("Top250各地区平均评分") save_fig("10_Top250_地区特征分析") Top250 评分分布 plt.figure(figsize=(10, 6)) sns.histplot(df_top250["评分"], bins=10, kde=True, color="#96CEB4") plt.title("Top250电影评分分布") save_fig("11_Top250_评分分布特征")

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/19 10:16:08

一台游戏机怎么喂饱全家屏幕?Sunshine 串流主机搭建全记录

一台游戏机怎么喂饱全家屏幕&#xff1f;Sunshine 串流主机搭建全记录 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine Sunshine 是一款免费开源的游戏串流服务器&#xff0c;它的使…

作者头像 李华
网站建设 2026/8/19 10:15:46

RT-Thread SPI驱动移植实战:HC32F460硬件抽象层实现与调试

1. 项目缘起&#xff1a;当RT-Thread遇上HC32F460的SPI 最近在做一个基于华大半导体HC32F460的嵌入式项目&#xff0c;核心需求是通过SPI接口连接一块外部的Flash存储芯片。项目选用了RT-Thread作为实时操作系统&#xff0c;看中的就是它丰富的驱动框架和活跃的社区生态。本以为…

作者头像 李华
网站建设 2026/8/19 10:15:35

数码产品购物商城源码 Java+SpringBoot+Vue 万字文档+PPT 前后分离

一、关键词数码产品购物商城&#xff0c;数码产品电商交易平台&#xff0c;数码用品网上商城系统二、作品包含源码数据库万字设计文档PPT全套环境和工具资源本地部署教程三、项目技术前端技术&#xff1a;Html、Css、Js、Vue2、Element-ui后端技术&#xff1a;Java、SpringBoot…

作者头像 李华
网站建设 2026/8/19 10:14:38

Arduino Uno最小系统搭建:从ATmega328P核心电路到PCB设计全解析

1. 项目概述&#xff1a;什么是“骨架版”Arduino Uno&#xff1f; 如果你玩过Arduino&#xff0c;大概率接触过那块经典的蓝色小板子——Arduino Uno。它集成了ATmega328P微控制器、USB转串口芯片、电源管理、LED指示灯和一堆排针&#xff0c;开箱即用&#xff0c;非常方便。但…

作者头像 李华
网站建设 2026/8/19 10:10:32

基于Micro:bit的温度测量项目实践:从内置传感器到外部扩展

1. 项目缘起&#xff1a;为什么用Micro:bit做温度计&#xff1f; 如果你手头正好有一块BBC Micro:bit&#xff0c;或者正想给孩子、学生或者自己找一个简单又有趣的电子入门项目&#xff0c;那么做一个温度测量装置绝对是个绝佳的选择。这听起来可能有点“小儿科”&#xff0c;…

作者头像 李华
网站建设 2026/8/19 10:10:08

对话式AI的信任机制:温暖感与用户特质如何影响验证决策

1. 项目缘起&#xff1a;一个被忽视的决策拐点在信息爆炸的时代&#xff0c;我们每天都在与各种对话式智能体&#xff08;Conversational Agents, CAs&#xff09;打交道&#xff0c;无论是手机里的语音助手、网页上的客服机器人&#xff0c;还是功能日益强大的通用聊天机器人。…

作者头像 李华