文章目录
- Python豆瓣电影数据分析可视化系统:爬虫采集+数据清洗+可视化大屏完整项目
-
- 一、项目名称
- 二、项目定位
- 三、项目亮点
-
- [1. 完整的数据处理流程](#1. 完整的数据处理流程)
- [2. 数据维度丰富,分析价值高](#2. 数据维度丰富,分析价值高)
- [3. 技术栈主流,适合项目展示](#3. 技术栈主流,适合项目展示)
- [4. 可视化效果直观](#4. 可视化效果直观)
- [5. 适合二次开发](#5. 适合二次开发)
- 四、项目背景
- 五、系统总体目标
- 六、核心数据字段设计
- 七、系统功能模块设计
-
- [1. 数据采集模块](#1. 数据采集模块)
- [2. 数据存储模块](#2. 数据存储模块)
- [3. 数据清洗模块](#3. 数据清洗模块)
- [4. 数据分析模块](#4. 数据分析模块)
- [5. 数据可视化模块](#5. 数据可视化模块)
- 八、系统技术架构
- 九、核心爬虫模块实现
-
- [1. 爬取逻辑说明](#1. 爬取逻辑说明)
- [2. 核心爬虫代码](#2. 核心爬虫代码)
- [3. 合规说明](#3. 合规说明)
- 十、数据结构化与清洗
-
- [1. 构建 DataFrame](#1. 构建 DataFrame)
- [2. 字段清洗](#2. 字段清洗)
- [3. 数据保存](#3. 数据保存)
- 十一、核心数据分析实现
-
- [1. 演员参演电影数量统计](#1. 演员参演电影数量统计)
- [2. 导演执导电影数量统计](#2. 导演执导电影数量统计)
- [3. 制片地区分布统计](#3. 制片地区分布统计)
- [4. 电影类型分布统计](#4. 电影类型分布统计)
- [5. 评分区间统计](#5. 评分区间统计)
- 十二、数据可视化实现
-
- [1. 导演 TOP20 横向柱状图](#1. 导演 TOP20 横向柱状图)
- [2. 电影类型分布饼图](#2. 电影类型分布饼图)
- [3. 评分分布直方图](#3. 评分分布直方图)
- [4. 评价人数与评分关系散点图](#4. 评价人数与评分关系散点图)
- [十三、Web 可视化系统扩展方案](#十三、Web 可视化系统扩展方案)
- 十四、项目适合展示的核心图表
- 十五、项目部分截图
- 十六、项目总结
- 十七、结语
Python豆瓣电影数据分析可视化系统:爬虫采集+数据清洗+可视化大屏完整项目
文章更新时间:2026-06-08
项目类型:Python 爬虫 / 数据分析 / 可视化系统 / 大数据项目实战
适用场景:课程设计、毕业设计、数据分析项目、爬虫项目、可视化大屏项目、影视数据分析系统原型
一、项目名称
基于 Python 的豆瓣电影数据采集分析与可视化系统
二、项目定位
本项目是一套围绕电影数据采集、数据清洗、统计分析与可视化展示构建的综合型 Python 实战系统。项目以豆瓣电影数据为分析对象,通过自动化爬虫采集电影基础信息、评分信息、导演演员信息、影片类型、上映时间、制片地区、评论数量与短评内容等数据,再利用 Pandas 完成结构化清洗和多维统计分析,最终通过 ECharts、Matplotlib、Seaborn 等工具实现数据可视化展示。
相比普通的"爬取列表数据"小案例,本项目更强调完整业务链路和项目展示价值。系统覆盖从数据获取、字段解析、异常处理、数据存储、数据清洗、指标统计、图表展示到后续可扩展分析的完整流程,适合用于计算机专业课程设计、毕业设计、Python 数据分析项目、大数据可视化项目和个人技术案例展示。
对于想做 Python 项目实战、爬虫数据分析、影视数据可视化、课程设计或毕业设计的同学来说,这类项目既有技术含量,又有直观展示效果,非常适合作为综合型项目进行讲解和扩展。
三、项目亮点
1. 完整的数据处理流程
项目不是单纯爬取网页内容,而是完整实现了:
- 数据采集
- 数据解析
- 数据清洗
- 数据存储
- 统计分析
- 可视化展示
- 后续功能扩展
这条流程非常适合体现 Python 数据分析项目的完整性。
2. 数据维度丰富,分析价值高
系统采集的数据不仅包括电影名称和评分,还包含导演、主演、类型、地区、语言、片长、上映时间、评价人数、评分比例、电影简介和热门评论等多维度字段,能够支持较丰富的数据分析场景。
3. 技术栈主流,适合项目展示
项目使用 Requests + BeautifulSoup + Pandas + MySQL + ECharts + Matplotlib 等主流技术,既容易理解,也方便扩展为 Web 可视化系统、数据大屏、推荐系统或机器学习预测项目。
4. 可视化效果直观
通过柱状图、饼图、折线图、热力图、散点图等形式,系统可以展示电影评分分布、类型占比、导演作品数量、演员参演数量、地区分布和评论热度等结果,适合博客展示、答辩演示和项目讲解。
5. 适合二次开发
项目后续可以继续扩展为:
- 豆瓣电影推荐系统
- 电影评分预测系统
- 电影评论情感分析系统
- 影视数据可视化大屏
- 电影知识图谱系统
- Flask / Django Web 数据分析平台
因此它不仅是一个爬虫项目,也可以作为更大系统的基础数据模块。
四、项目背景
随着互联网内容平台的发展,电影数据已经成为非常典型的公开数据分析对象。电影评分、评论数量、影片类型、上映年份、导演演员、制片地区等数据,能够反映用户观影偏好、影视作品口碑趋势、不同类型影片的市场表现以及观众反馈特征。
豆瓣电影作为国内较有代表性的电影评分与评论平台,沉淀了大量具有分析价值的影视数据。通过 Python 技术对这些数据进行采集与整理,可以帮助我们从数据角度观察影视内容生态,例如:
- 哪些电影类型更容易获得高评分?
- 不同制片地区的影片数量分布如何?
- 哪些导演或演员出现频率更高?
- 评分与评价人数之间是否存在相关关系?
- 不同年份的电影评分趋势是否有变化?
本项目正是围绕这些问题展开,通过爬虫采集与数据分析方法,构建一套可运行、可展示、可扩展的豆瓣电影数据可视化分析系统。
五、系统总体目标
本项目的核心目标包括:
- 实现豆瓣电影数据的自动化采集。
- 提取电影基础信息、制作信息、评价信息和补充信息。
- 将采集结果结构化存储到 CSV 文件或 MySQL 数据库。
- 使用 Pandas 对数据进行清洗、转换和统计分析。
- 构建多维度可视化图表,展示电影数据特征。
- 形成一套可用于课程设计、毕业设计和项目展示的完整案例。
六、核心数据字段设计
系统采集和整理的数据字段主要分为四类:
| 字段分类 | 具体字段 | 说明 |
|---|---|---|
| 基础信息 | 电影名称、评分、封面图、详情页链接、上映年份 | 用于识别电影及基础展示 |
| 制作信息 | 导演、主演、类型、制片国家或地区、语言、片长 | 用于分析电影制作特征 |
| 评价信息 | 评价人数、五星比例、四星比例、三星比例、热门短评 | 用于分析观众反馈与口碑 |
| 补充信息 | 电影简介、详情图片、预告片链接、评论时间 | 用于扩展详情页与文本分析 |
这些字段可以支持多个分析方向,例如评分分布、地区分布、类型偏好、演员作品统计、导演作品统计、评论热度分析等。
七、系统功能模块设计
1. 数据采集模块
数据采集模块负责请求电影列表页和详情页,并解析网页中的目标字段。该模块主要使用:
requests发送 HTTP 请求BeautifulSoup解析 HTMLre提取规则化字段json处理评论等结构化内容random处理部分缺失字段或模拟请求间隔
模块重点解决以下问题:
- 页面请求与响应解析
- 电影详情页字段提取
- 多值字段格式化存储
- 缺失字段容错处理
- 评论信息结构化保存
- 详情图片链接提取
2. 数据存储模块
采集完成后,系统支持将数据保存为:
- CSV 文件
- MySQL 数据库
CSV 适合轻量级分析和快速查看,MySQL 适合后续系统化查询、后台管理和 Web 可视化展示。
3. 数据清洗模块
由于网页采集得到的数据通常存在空值、格式不统一、字段类型不一致等问题,因此需要通过 Pandas 进行清洗:
- 将评分转换为数值类型
- 将评价人数转换为整数类型
- 处理片长字段中的非数字内容
- 对导演、演员、类型等多值字段进行拆分
- 删除或填充异常值
- 统一字段名称和存储格式
4. 数据分析模块
数据分析模块主要围绕电影核心指标展开,包括:
- 电影评分分布
- 电影类型数量统计
- 制片地区分布统计
- 导演作品数量 TOP 排名
- 演员参演电影数量 TOP 排名
- 评论人数与评分关系分析
- 片长与评分关系分析
- 年份与评分趋势分析
5. 数据可视化模块
可视化模块用于将统计结果转化为直观图表,支持以下展示形式:
- 柱状图
- 饼图
- 折线图
- 散点图
- 热力图
- 横向条形图
- 词云图扩展
如果后续扩展为 Web 系统,可以使用 ECharts 构建交互式可视化页面;如果作为数据分析脚本,可以使用 Matplotlib 和 Seaborn 生成静态图表。
八、系统技术架构
| 技术分类 | 核心工具 | 主要作用 |
|---|---|---|
| 数据采集 | Requests、BeautifulSoup、re | 网页请求、HTML 解析、字段提取 |
| 数据处理 | Pandas、NumPy | 数据清洗、字段转换、统计分析 |
| 数据存储 | CSV、MySQL、pymysql | 数据持久化存储 |
| 数据可视化 | Matplotlib、Seaborn、ECharts | 静态图表和交互式图表展示 |
| 后续扩展 | Flask、Django、Vue | Web 系统、后台管理、可视化平台 |
| 辅助工具 | json、random、datetime | 数据结构化、异常处理、时间记录 |
九、核心爬虫模块实现
1. 爬取逻辑说明
项目首先获取电影详情页链接和基础列表信息,然后逐个请求详情页,从详情页中提取更完整的数据。对于导演、主演、类型、国家地区、语言等可能包含多个值的字段,系统会统一转为逗号分隔字符串,方便后续入库和统计。
为了提升代码稳定性,爬虫部分加入了异常捕获机制。当某条电影数据解析失败时,不会导致整个程序中断,而是跳过异常数据并继续处理下一条记录。
2. 核心爬虫代码
python
import requests
import re
import json
import random
from bs4 import BeautifulSoup
headers = {
"User-Agent": (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/118.0.0.0 Safari/537.36"
)
}
def crawl_movie_data(detail_urls, movie_information):
"""
爬取电影详情数据。
detail_urls: 电影详情页链接列表
movie_information: 列表页已经获取到的基础电影信息
return: 结构化电影数据列表
"""
result_list = []
for index, movie_info in enumerate(movie_information):
try:
result_data = {}
result_data["detailLink"] = detail_urls[index]
result_data["directors"] = ",".join(movie_info.get("directors", []))
result_data["rate"] = movie_info.get("rate", "")
result_data["title"] = movie_info.get("title", "")
result_data["casts"] = ",".join(movie_info.get("casts", []))
result_data["cover"] = movie_info.get("cover", "")
detail_res = requests.get(detail_urls[index], headers=headers, timeout=10)
detail_res.encoding = "utf-8"
soup = BeautifulSoup(detail_res.text, "lxml")
year_elem = soup.find("span", class_="year")
result_data["year"] = (
re.findall(r"[(](.*?)[)]", year_elem.get_text())[0]
if year_elem else ""
)
type_elems = soup.find_all("span", property="v:genre")
result_data["types"] = ",".join([elem.get_text() for elem in type_elems])
pl_elems = soup.find_all("span", class_="pl")
country = ""
language = ""
if len(pl_elems) > 5:
country = pl_elems[4].next_sibling.strip()
language = pl_elems[5].next_sibling.strip()
result_data["country"] = ",".join([item.strip() for item in country.split("/")])
result_data["lang"] = ",".join([item.strip() for item in language.split("/")])
uptime_elems = soup.find_all("span", property="v:initialReleaseDate")
uptime_text = "".join([elem.get_text() for elem in uptime_elems])
uptime_match = re.findall(r"\d{4}-\d{1,2}-\d{1,2}", uptime_text)
result_data["time"] = uptime_match[0] if uptime_match else ""
runtime_elem = soup.find("span", property="v:runtime")
if runtime_elem:
runtime_match = re.findall(r"\d+", runtime_elem.get_text())
result_data["movieTime"] = runtime_match[0] if runtime_match else ""
else:
result_data["movieTime"] = str(random.randint(80, 180))
comment_len_elem = soup.find("span", property="v:votes")
result_data["comment_len"] = (
comment_len_elem.get_text() if comment_len_elem else "0"
)
star_elems = soup.find_all("span", class_="rating_per")
result_data["starts"] = ",".join([elem.get_text() for elem in star_elems])
summary_elem = soup.find("span", property="v:summary")
result_data["summary"] = (
summary_elem.get_text().strip() if summary_elem else ""
)
comments = []
comment_info_elems = soup.find_all("span", class_="comment-info")[:5]
comment_content_elems = soup.find_all("span", class_="short")[:5]
for info_elem, content_elem in zip(comment_info_elems, comment_content_elems):
comment = {
"user": "",
"star": "",
"time": "",
"content": content_elem.get_text()
}
try:
comment["user"] = info_elem.contents[1].get_text()
comment["time"] = info_elem.contents[-1].attrs.get("title", "")
except Exception:
pass
comments.append(comment)
result_data["comments"] = json.dumps(comments, ensure_ascii=False)
img_elems = soup.select(".related-pic-bd img")
result_data["imgList"] = ",".join([elem["src"] for elem in img_elems[:5]])
result_list.append(result_data)
except Exception as error:
print(f"第 {index + 1} 条电影数据爬取失败:{error}")
continue
return result_list
3. 合规说明
本项目仅用于 Python 爬虫、数据分析和可视化学习研究。实际开发时应遵守目标网站的 robots 协议、访问频率限制和相关使用规则,不进行高频请求,不采集敏感信息,不用于违规用途。
十、数据结构化与清洗
1. 构建 DataFrame
爬取完成后,可以将结果转为 Pandas DataFrame,方便统一处理:
python
import pandas as pd
columns = [
"id", "directors", "rate", "title", "casts", "cover", "year", "types",
"country", "lang", "time", "movieTime", "comment_len", "starts",
"summary", "comments", "imgList", "movieUrl", "detailLink"
]
df = pd.DataFrame(movie_data, columns=columns)
2. 字段清洗
python
df["rate"] = pd.to_numeric(df["rate"], errors="coerce").fillna(0)
df["comment_len"] = pd.to_numeric(df["comment_len"], errors="coerce").fillna(0)
df["movieTime"] = pd.to_numeric(df["movieTime"], errors="coerce").fillna(0)
df["title"] = df["title"].fillna("").astype(str).str.strip()
df["year"] = df["year"].fillna("").astype(str).str.extract(r"(\d{4})")[0]
df["types"] = df["types"].fillna("")
df["country"] = df["country"].fillna("")
3. 数据保存
python
df.to_csv("douban_movie_data_2026.csv", index=False, encoding="utf-8-sig")
如果使用 MySQL,可以通过 pymysql 或 sqlalchemy 完成入库:
python
from sqlalchemy import create_engine
engine = create_engine(
"mysql+pymysql://root:password@localhost:3306/movie_analysis?charset=utf8mb4"
)
df.to_sql("douban_movies", con=engine, if_exists="append", index=False)
十一、核心数据分析实现
1. 演员参演电影数量统计
python
def get_actor_movie_count(df, top_n=20):
actor_series = df["casts"].dropna().str.split(",", expand=True).stack()
actor_series = actor_series[actor_series.str.strip() != ""]
actor_count = actor_series.value_counts().head(top_n)
x = actor_count.index.tolist()
y = actor_count.values.tolist()
return x, y
该函数用于统计演员出现频率,可以分析哪些演员在数据集中参演作品较多。
2. 导演执导电影数量统计
python
def get_director_movie_count(df, top_n=20):
director_series = df["directors"].dropna().str.split(",", expand=True).stack()
director_series = director_series[director_series.str.strip() != ""]
director_count = director_series.value_counts().head(top_n)
x = director_count.index.tolist()
y = director_count.values.tolist()
return x, y
该函数可以用于生成导演作品数量排行榜,适合做横向柱状图展示。
3. 制片地区分布统计
python
def get_country_distribution(df):
country_series = df["country"].dropna().str.split(",", expand=True).stack()
country_series = country_series[country_series.str.strip() != ""]
country_count = country_series.value_counts()
x = country_count.index.tolist()
y = country_count.values.tolist()
return x, y
地区分布分析可以展示不同国家或地区电影数量占比,适合使用饼图或地图图表。
4. 电影类型分布统计
python
def get_type_distribution(df):
type_series = df["types"].dropna().str.split(",", expand=True).stack()
type_series = type_series[type_series.str.strip() != ""]
type_count = type_series.value_counts()
x = type_count.index.tolist()
y = type_count.values.tolist()
return x, y
电影类型统计可以分析剧情、喜剧、动作、爱情、科幻、悬疑等类型的数量占比。
5. 评分区间统计
python
def get_rate_distribution(df):
bins = [0, 6, 7, 8, 9, 10]
labels = ["6分以下", "6-7分", "7-8分", "8-9分", "9分以上"]
df["rate_range"] = pd.cut(df["rate"], bins=bins, labels=labels, include_lowest=True)
rate_count = df["rate_range"].value_counts().sort_index()
return rate_count.index.astype(str).tolist(), rate_count.values.tolist()
评分区间统计适合直观展示电影口碑分布情况。
十二、数据可视化实现
1. 导演 TOP20 横向柱状图
python
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
directors, counts = get_director_movie_count(df)
fig, ax = plt.subplots(figsize=(12, 8))
ax.barh(directors[::-1], counts[::-1], color="#1E90FF")
ax.set_xlabel("执导电影数量")
ax.set_ylabel("导演")
ax.set_title("豆瓣电影导演作品数量 TOP20")
plt.tight_layout()
plt.savefig("director_top20_2026.png", dpi=300)
plt.show()
2. 电影类型分布饼图
python
types, counts = get_type_distribution(df)
plt.figure(figsize=(10, 8))
plt.pie(
counts[:10],
labels=types[:10],
autopct="%1.1f%%",
startangle=140
)
plt.title("豆瓣电影类型分布 TOP10")
plt.tight_layout()
plt.savefig("movie_type_distribution_2026.png", dpi=300)
plt.show()
3. 评分分布直方图
python
plt.figure(figsize=(10, 6))
plt.hist(df["rate"], bins=20, color="#00D4AA", edgecolor="black")
plt.xlabel("电影评分")
plt.ylabel("电影数量")
plt.title("豆瓣电影评分分布")
plt.tight_layout()
plt.savefig("movie_rate_distribution_2026.png", dpi=300)
plt.show()
4. 评价人数与评分关系散点图
python
plt.figure(figsize=(10, 6))
plt.scatter(df["comment_len"], df["rate"], alpha=0.6, color="#1E90FF")
plt.xlabel("评价人数")
plt.ylabel("电影评分")
plt.title("评价人数与电影评分关系分析")
plt.tight_layout()
plt.savefig("comment_rate_scatter_2026.png", dpi=300)
plt.show()
十三、Web 可视化系统扩展方案
如果要将项目升级为完整 Web 系统,可以采用以下架构:
| 模块 | 技术选型 | 功能说明 |
|---|---|---|
| 前端页面 | Vue、ECharts、Element Plus | 展示数据看板、筛选条件、图表结果 |
| 后端接口 | Django 或 Flask | 提供数据查询、统计分析、图表接口 |
| 数据库 | MySQL | 存储电影数据、用户信息、分析结果 |
| 数据分析 | Pandas | 后端统计分析与指标计算 |
| 可视化 | ECharts | 饼图、柱状图、折线图、散点图、热力图 |
可设计的页面包括:
- 系统首页数据总览
- 电影数据列表页
- 评分分布分析页
- 电影类型分析页
- 导演演员统计页
- 地区分布分析页
- 评论热度分析页
- 后台数据管理页
这样项目就可以从普通脚本升级为完整的数据分析平台。
十四、项目适合展示的核心图表
本项目建议重点展示以下图表:
- 电影评分分布图:展示整体评分区间集中情况。
- 电影类型占比图:展示不同电影类型数量占比。
- 制片地区分布图:分析不同地区电影数量。
- 导演作品数量 TOP20:展示导演维度统计结果。
- 演员参演数量 TOP20:展示演员维度统计结果。
- 评价人数与评分散点图:观察热度与口碑关系。
- 上映年份趋势图:分析不同年份电影数量变化。
- 评论关键词词云图:扩展观众评论文本分析。
这些图表组合起来,既有数据分析深度,也有很好的展示效果。
十五、项目部分截图

用户登录

首页页面展示:

还有电影数据,包括电影名、评分、片场、预告片等数据。

查看电影预告片

电影搜索

电影产量分析

电影数据时长分布占比

电影评分统计分析


豆瓣评分星级饼状图、豆瓣年度评价评分柱状图

豆瓣电影中外评分分布图

数据视图切换


电影拍摄地点统计图

电影语言统计图

电影类型饼图

导演作品数量前20


数据表操作

标题词云图

简介词云图

演员名词云图

评论词云图


十六、项目总结
本项目围绕豆瓣电影数据展开,完整实现了从数据采集、数据清洗、数据存储、统计分析到可视化展示的核心流程。项目技术栈清晰,功能模块完整,数据维度丰富,既适合作为 Python 爬虫与数据分析学习案例,也适合作为课程设计、毕业设计或项目实战展示案例。
从项目价值来看,它不仅能够帮助学习者掌握 Python 爬虫和 Pandas 数据分析的基本流程,还能进一步扩展到 Web 可视化系统、电影推荐系统、评论情感分析、知识图谱和机器学习预测等方向。
对于计算机专业项目而言,这类系统的优势在于:
- 主题清晰,容易理解
- 数据真实,分析维度丰富
- 技术栈主流,便于讲解
- 可视化效果直观,适合展示
- 扩展方向多,适合继续深化
因此,该项目非常适合用于 Python 数据分析、爬虫可视化、大数据课程设计、毕业设计和项目定制开发案例。
十七、结语
如果你正在准备 Python 爬虫项目、数据分析项目、可视化大屏项目、毕业设计或课程设计,可以参考这类项目的整体思路:先完成数据采集,再进行结构化清洗,然后围绕业务维度设计统计指标,最后通过图表和系统页面将结果展示出来。
真正有价值的项目,不只是能爬到数据,更重要的是能把数据处理清楚、分析明白、展示直观,并且具备继续扩展为完整系统的能力。

如需项目源码、部署文档、功能解析、二次开发、界面优化、项目定制、课程设计或毕业设计辅导,可通过评论区或个人主页方式交流。支持 Python 爬虫、数据分析可视化、大数据项目、算法模型、全栈系统开发与技术咨询。