拓冰建站拓冰建站
首页 / 资讯中心 / 正文

用Python爬虫与数据分析,一次看完《狂蟒之灾》系列口碑走向

最近在补老片的时候突然想认真看完《狂蟒之灾》整个系列。但只看电影列表和简介很难快速判断哪一部的口碑更好、哪一部评分暴跌、整个系列到底经历了什么变化。于是我干脆写了一套 Python 脚本把系列电影的基础数据、评分、票房、时长以及字幕关键词全部拉下来做分析用数据“一口气看完”这一整部经典恐怖片系列。这篇文章就完整记录整个数据分析过程包括数据获取、清洗、可视化分析和字幕文本挖掘代码都可以直接跑新手也能一步步复现。## 1. 背景与核心概念 ### 1.1 《狂蟒之灾》系列为什么值得做数据分析 《狂蟒之灾》是索尼哥伦比亚影业推出的怪兽恐怖片系列第一部于 1997 年上映讲述一支纪录片摄制组在亚马逊雨林拍摄时遭遇巨型蟒蛇袭击的故事。这个系列最大的特点是它不是一个导演从头拍到尾的连续剧集而是经历了主演更替、导演换人、世界观微调的过程甚至从第二部开始弱化了演员戏份把重点放到蟒蛇特效上。 对于普通观众来说想快速了解这个系列最直观的方式不是一篇篇翻影评而是用一个数据表把各部电影的关键指标摆在一起。比如 - 系列一共有多少部 - 各部电影的上映时间跨度有多大 - 评分和票房是上升还是下降 - 每一部的片长、制作模式有什么变化 这些问题用 Python 的爬虫和数据分析工具可以在很短时间内得到答案。这个过程本身可以帮你建立起一套“电影数据快速分析”的通用技能以后分析其他系列电影也能复用。 ### 1.2 本节涉及的技术概念 在正式开始之前先理清本文会用到的几个核心概念方便零基础读者跟上。 **爬虫Web Scraping**通过程序自动请求网页并提取信息的过程。简单理解就是写一个程序模拟浏览器访问某个电影资料页面然后从网页 HTML 里把电影名称、上映日期、评分、票房等信息抽取出来。 **数据清洗Data Cleaning**从网页或接口拿到的原始数据通常不干净可能是字符串、可能包含缺失值、可能有重复项需要经过处理后才能进行分析。Pandas 是 Python 里最常用的数据处理库。 **数据可视化Data Visualization**把处理好的数字表格转化为图表。人看数字不够直观但看折线图和柱状图很快就能明白趋势。Matplotlib 是 Python 的基础绘图库。 **文本词频分析Text Frequency Analysis**把一部电影的字幕文本拆成一个个词统计每个词出现的次数从而了解电影的高频关键词。比如一部恐怖片里“蛇”“森林”“跑”出现的频率如果很高就能侧面印证它是一部动作逃生片。 ### 1.3 这类分析适合什么场景 这套分析流程并不只适用于《狂蟒之灾》它其实是一套通用的“影视系列数据分析模板”。举几个场景 - 想做一个“漫威系列电影观看顺序”的工具需要整理上映时间、剧情时间线。 - 想分析某个导演的所有作品口碑趋势按年份画一张评分折线图。 - 想对比同一 IP 的真人版和动画版收集两个版本各项指标做横向对比。 - 想快速了解某个恐怖片系列的质量分布决定从哪一部开始补课。 换句话说读完这篇文章你掌握的是一整套从采集、清洗到可视化的影视分析思路而不仅仅是解决一部电影的分析问题。 ## 2. 环境准备与版本说明 ### 2.1 开发环境 本文的示例代码基于以下环境版本可以根据你的实际环境调整重点演示分析思路 | 项目 | 说明 | | --- | --- | | 操作系统 | Windows 10 / macOS / Linux 均可 | | Python | 3.8 及以上 | | 开发工具 | PyCharm / VS Code / Jupyter Notebook | | 运行方式 | 命令行运行 Python 脚本 | | 核心库 | requests、pandas、matplotlib、jieba | 建议在正式写代码前为这个项目单独创建一个虚拟环境避免不同项目之间依赖库版本冲突。 bash python -m venv anaconda_env source anaconda_env/bin/activate # Windows 下执行 anaconda_env\Scripts\activate2.2 依赖库安装本文会用到以下库requests发送 HTTP 请求获取网页内容。beautifulsoup4解析 HTML提取想要的字段。pandas数据表格处理。matplotlib绘制折线图、柱状图。jieba中文分词用于字幕文本分析。wordcloud生成词云图可选视觉效果好。安装命令如下pip install requests beautifulsoup4 pandas matplotlib jieba wordcloud需要说明的是不同库之间的版本兼容性一般不会有太大问题但如果你的 Python 版本较老建议先升级 pip 再安装pip install --upgrade pip2.3 项目目录结构为了让代码更清晰我建议将工程拆成下面这样的目录结构anaconda_analysis/ ├── data/ # 存放原始数据和中间数据 │ ├── raw/ │ └── processed/ ├── output/ # 存放图表输出 ├── crawler.py # 爬虫脚本负责数据采集 ├── clean.py # 数据清洗脚本 ├── analyze.py # 数据分析和可视化脚本 ├── subtitle_analysis.py # 字幕词频分析脚本 └── requirements.txt # 依赖清单这样拆分的好处是采集、清洗、分析各步骤互相独立修改某一个环节不会影响其他环节。下面我们逐步实现每个模块。3. 核心知识拆解3.1 爬虫采集从网页中提取电影信息爬虫的基本逻辑只有三步请求网页、解析内容、保存数据。在 Python 中requests库负责请求网页BeautifulSoup负责解析 HTML。下面是一个最小示例演示如何从网页中提取电影标题。import requests from bs4 import BeautifulSoup url https://example.com/movie headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } response requests.get(url, headersheaders, timeout10) soup BeautifulSoup(response.text, html.parser) # 假设电影标题在 h1 标签中class 为 movie-title title_tag soup.find(h1, class_movie-title) if title_tag: print(电影标题:, title_tag.get_text(stripTrue))这段代码里有几个需要注意的细节headers里的User-Agent是模拟真实浏览器请求头部分网站会拦截默认的 Python 请求头。timeout10指定超时时间避免请求卡住。get_text(stripTrue)可以去掉提取文本前后的空格和换行。在实际采集《狂蟒之灾》系列数据时你可能需要遍历多部电影的详情页每一页的结构不完全相同因此建议先用单页测试解析逻辑确认能提取到正确字段后再批量采集。3.2 Pandas 数据清洗处理缺失值和类型转换从网页提取到的数据通常是字符串例如评分可能是5.4 / 10这种格式票房可能是139.8 million。这种数据不能直接做数学运算必须先清洗。Pandas 处理表格数据非常方便。假设我们已经把爬取的结果保存成了一个 CSV 文件可以用下面的方式读取并清洗import pandas as pd df pd.read_csv(data/raw/anaconda_series_raw.csv) print(df.head()) print(df.info())df.info()会展示每一列的数据类型和非空数量从输出里可以判断哪些字段需要清洗。常见操作包括删除完全为空的行。填充缺失值。将字符串数字转换成 float。将年份字符串转换成整数。来看一个具体的转换示例# 假设评分列格式为 5.4 / 10 df[score] df[rating].str.extract(r([\d.])).astype(float) # 假设票房列格式为 139.8 million df[box_office_million] ( df[box_office] .str.extract(r([\d.])) .astype(float) )这里用到了正则表达式提取数字部分是数据清洗中非常常见的手段。str.extract是 Pandas 提供的字符串处理函数配合正则表达式可以从复杂的字符串中抽取目标数值。3.3 Matplotlib 可视化直观展示趋势当数据被清洗成规范的 DataFrame 后就可以开始可视化。Matplotlib 是 Python 最基础的绘图库其他高级库比如 Seaborn也都是基于它封装的。我们想做一张“《狂蟒之灾》系列各部电影的评分走势折线图”代码可以这样写import matplotlib.pyplot as plt import pandas as pd plt.rcParams[font.sans-serif] [SimHei] # 解决中文显示问题 plt.rcParams[axes.unicode_minus] False # 解决负号显示问题 df pd.read_csv(data/processed/anaconda_cleaned.csv) plt.figure(figsize(10, 5)) plt.plot( df[year], df[score], markero, linestyle-, linewidth2, markersize6, ) plt.title(《狂蟒之灾》系列评分走势) plt.xlabel(上映年份) plt.ylabel(评分) plt.grid(True, linestyle--, alpha0.5) for x, y in zip(df[year], df[score]): plt.text(x, y 0.1, str(y), hacenter, fontsize10) plt.tight_layout() plt.savefig(output/score_trend.png, dpi300) plt.show()这里有几个容易踩坑的地方中文字体显示在 Windows 上一般用SimHeimacOS 可以用PingFang SCLinux 需要安装中文字体。dpi300可以让保存的图片更清晰适合直接放进文档或 PPT。plt.tight_layout()避免图片边缘被截断。运行这段代码后如果一切顺利你会在屏幕上看到一张折线图并且图片会保存到 output 目录。3.4 字幕文本分析用词频发现电影主题除了结构化数据电影的字幕文本也是很重要的分析素材。字幕文件通常是 srt 格式里面包含序号、时间轴和字幕文本。我们可以用正则表达式把纯文本提取出来再用 jieba 分词统计高频词。下面是一个完整的字幕预处理示例import re import jieba from collections import Counter def extract_srt_text(srt_path): with open(srt_path, r, encodingutf-8) as f: content f.read() # 去掉序号和时间轴 content re.sub(r\d\n, , content) content re.sub(r\d{2}:\d{2}:\d{2},\d{3} -- \d{2}:\d{2}:\d{2},\d{3}, , content) content re.sub(r[^], , content) # 去掉字幕样式标签 lines [line.strip() for line in content.splitlines() if line.strip()] return \n.join(lines) text extract_srt_text(data/raw/anaconda1.srt) words jieba.lcut(text) words [w for w in words if len(w) 1 and w.isalpha()] counter Counter(words) for word, count in counter.most_common(20): print(word, count)在这个示例里jieba.lcut是把句子切分成词语列表Counter是 Python 内置的计数类most_common返回出现次数最多的词。字幕文本经过这样的处理后就能快速看到电影文本的高频词。4. 完整实战案例这一节我们把前面拆解的知识点整合成一套完整的代码实现“一口气看完”《狂蟒之灾》系列的数据分析。4.1 创建项目结构先在命令行中创建项目目录mkdir anaconda_analysis cd anaconda_analysis mkdir data/raw data/processed output然后把之前安装依赖时生成的 requirements 文件补全pip freeze requirements.txt4.2 编写采集脚本 crawler.py为了提高可读性我们把采集逻辑封装成函数。这里以豆瓣电影搜索页作为示例数据源思路具体的 URL 和字段提取方式需要按你实际访问的页面结构调整。import requests from bs4 import BeautifulSoup import time BASE_URL https://example.com/search HEADERS { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def fetch_movie_info(keyword): 根据关键词搜索电影并返回基础信息列表。 params {q: keyword} response requests.get(BASE_URL, headersHEADERS, paramsparams, timeout10) if response.status_code ! 200: print(请求失败状态码:, response.status_code) return [] soup BeautifulSoup(response.text, html.parser) movies [] for item in soup.select(.movie-item): # 选择器根据实际页面调整 title item.select_one(.title) year item.select_one(.year) rating item.select_one(.rating) if title: movies.append({ title: title.get_text(stripTrue), year: year.get_text(stripTrue) if year else , rating: rating.get_text(stripTrue) if rating else , }) return movies if __name__ __main__: all_movies [] for keyword in [狂蟒之灾]: all_movies.extend(fetch_movie_info(keyword)) time.sleep(1) # 礼貌爬取避免请求过快 print(f获取到 {len(all_movies)} 条数据)这里的设计思路很关键time.sleep(1)在两次请求之间做一个暂停降低对目标网站的请求压力也降低被限制的风险。实际编写爬虫时要遵守网站的 robots 协议内容仅用于学习研究。4.3 编写数据清洗脚本 clean.py采集到原始数据后下一步就是清洗。注意这里的示例数据格式是我为了演示统一构造的实际爬取的数据字段名和格式可能不同你需要根据自己的数据调整。import pandas as pd def clean_data(input_path, output_path): 清洗原始 CSV 数据。 df pd.read_csv(input_path) # 删除完全重复的行 df df.drop_duplicates() # 删除缺失严重的行 df df.dropna(subset[title]) # 转换年份为整数 df[year] pd.to_numeric(df[year], errorscoerce) # 提取评分中的数字部分 df[score] df[rating].str.extract(r([\d.])).astype(float) # 按年份排序 df df.sort_values(year).reset_index(dropTrue) df.to_csv(output_path, indexFalse, encodingutf-8-sig) print(f清洗完成共保存 {len(df)} 条数据到 {output_path}) return df if __name__ __main__: df clean_data(data/raw/anaconda_series_raw.csv, data/processed/anaconda_cleaned.csv) print(df.head())encodingutf-8-sig可以在保存 CSV 时带上 BOM这样用 Excel 打开不会出现中文乱码。这是一个非常实用的小技巧。4.4 编写分析和可视化脚本 analyze.py清洗完成后就可以进入分析环节。这个脚本实现三个功能展示整体概况、绘制评分折线图、绘制票房柱状图。import pandas as pd import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False def show_overview(df): 打印整体概况。 print( 系列电影概况 ) print(f总电影数{len(df)}) print(f上映年份范围{df[year].min()} - {df[year].max()}) print(f平均评分{df[score].mean():.2f}) print(f最高评分电影{df.loc[df[score].idxmax(), title]}) print(f最低评分电影{df.loc[df[score].idxmin(), title]}) def plot_score_trend(df): 绘制评分走势折线图。 plt.figure(figsize(10, 5)) plt.plot( df[year], df[score], markero, linestyle-, colordarkred, linewidth2, markersize8 ) for x, y in zip(df[year], df[score]): plt.text(x, y 0.15, f{y:.1f}, hacenter, fontsize11) plt.title(《狂蟒之灾》系列电影评分走势, fontsize16) plt.xlabel(上映年份, fontsize12) plt.ylabel(豆瓣评分, fontsize12) plt.grid(True, linestyle--, alpha0.5) plt.tight_layout() plt.savefig(output/score_trend.png, dpi300) plt.show() def plot_box_office(df): 绘制票房对比柱状图。 plt.figure(figsize(10, 5)) plt.bar( df[year].astype(str), df[box_office_million], colorsteelblue, edgecolorblack ) for x, y in zip(df[year], df[box_office_million]): plt.text(x, y 2, f{y:.1f}, hacenter, fontsize11) plt.title(《狂蟒之灾》系列单片票房对比百万美元, fontsize16) plt.xlabel(上映年份, fontsize12) plt.ylabel(票房百万美元, fontsize12) plt.grid(True, axisy, linestyle--, alpha0.5) plt.tight_layout() plt.savefig(output/box_office_bar.png, dpi300) plt.show() if __name__ __main__: df pd.read_csv(data/processed/anaconda_cleaned.csv) show_overview(df) plot_score_trend(df) plot_box_office(df)4.5 编写字幕词频分析脚本 subtitle_analysis.py字幕分析脚本负责读取 srt 字幕文件抽取出高频词并生成词云。这里我们复用前面 3.4 小节的函数并补充词云生成逻辑。import re import jieba from wordcloud import WordCloud from collections import Counter import matplotlib.pyplot as plt def extract_srt_text(srt_path): 从 srt 字幕文件提取纯文本。 with open(srt_path, r, encodingutf-8) as f: content f.read() content re.sub(r\d\n, , content) content re.sub(r\d{2}:\d{2}:\d{2},\d{3} -- \d{2}:\d{2}:\d{2},\d{3}, , content) content re.sub(r[^], , content) lines [line.strip() for line in content.splitlines() if line.strip()] return \n.join(lines) def generate_wordcloud(text, output_path): 根据文本生成词云图。 words .join(jieba.lcut(text)) wc WordCloud( font_pathsimhei.ttf, # 中文字体路径按实际环境调整 width800, height600, background_colorwhite, max_words100, ).generate(words) plt.figure(figsize(12, 9)) plt.imshow(wc, interpolationbilinear) plt.axis(off) plt.savefig(output_path, dpi300) plt.show() if __name__ __main__: text extract_srt_text(data/raw/anaconda1.srt) words jieba.lcut(text) words [w for w in words if len(w) 1 and w.isalpha()] counter Counter(words) print(高频词 TOP 20:) for word, count in counter.most_common(20): print(f{word}: {count}) generate_wordcloud(text, output/wordcloud.png)这段代码在生成词云时需要指定中文字体路径。Windows 系统下通常是C:/Windows/Fonts/simhei.ttfmacOS 下可能是/System/Library/Fonts/PingFang.ttc你需要根据自己系统实际路径修改。4.6 运行与验证把所有脚本准备完成后按顺序运行python crawler.py python clean.py python analyze.py python subtitle_analysis.py建议先单独运行第一个脚本确认采集数据正常后再运行后续脚本。如果爬虫没有拿到数据后面的清洗和分析都没有意义。每一步运行后检查对应目录下的输出文件是否生成确保数据在整个流程中正常流转。5. 常见问题与排查思路在实际跑这套代码的过程中我遇到过不少问题下面是几个高频问题及排查方法。问题现象常见原因解决思路requests请求超时网络不稳定或目标网站响应慢增加 time out 值添加重试机制获取不到网页内容缺少 User-Agent被服务器拦截在 headers 中添加浏览器的 User-Agent中文显示为方框matplotlib 默认字体不支持中文设置plt.rcParams[font.sans-serif]为系统中文字体str.extract提取不到数字正则表达式和实际字符串不匹配先打印原字符串调整正则以匹配实际情况CSV 用 Excel 打开乱码文件没有用带 BOM 的 UTF-8 编码保存保存时使用encodingutf-8-sigjieba 分词后出现很多单个字过滤条件不够严格增加len(w) 1或过滤停用词词云不显示中文未指定中文字体路径在 WordCloud 中设置 font_path 参数下面挑两个典型问题展开说明。问题 1requests 请求超时如果你在跑爬虫时遇到requests.exceptions.ConnectTimeout首先要检查网络是否正常然后可以在请求时增加超时时间和异常处理try: response requests.get(url, headersheaders, timeout15) response.raise_for_status() except requests.exceptions.Timeout: print(请求超时跳过该页面) except requests.exceptions.RequestException as e: print(请求异常:, e)raise_for_status()会在响应状态码为 4xx 或 5xx 时主动抛出异常方便你及时发现页面请求失败的情况。问题 2matplotlib 中文乱码这个问题非常常见。即使设置了中文字体如果系统里没有对应字体一样会乱码。可以先在 Python 中查看当前可用的字体再选择系统中存在的中文字体import matplotlib.font_manager as fm fonts [font.name for font in fm.fontManager.ttflist] for name in set(fonts): if Hei in name or Song in name or PingFang in name: print(name)运行后会输出系统中可用的中文字体名称把合适的名称填入plt.rcParams[font.sans-serif]即可。6. 最佳实践与工程建议6.1 爬虫部分写爬虫时首先要检查目标网站的 robots 协议遵守网站的访问规则。无论爬取什么数据都只用于个人学习和研究不要用于商业用途。在代码层面建议把请求逻辑封装成一个带重试机制的公共函数import time import requests from functools import wraps def retry_wrapper(max_retries3, delay1): def decorator(func): wraps(func) def wrapper(*args, **kwargs): for i in range(max_retries): try: return func(*args, **kwargs) except requests.exceptions.RequestException as e: if i max_retries - 1: raise e time.sleep(delay) return wrapper return decorator这样可以避免网络抖动导致整个任务失败。同时采集过程要控制请求频率建议在两次请求之间加 1 到 3 秒的随机延迟import random time.sleep(random.uniform(1, 3))6.2 数据处理部分数据清洗是整个分析过程中最耗时也最容易出错的环节。建议遵循以下原则每一步清洗操作都单独保存一个中间结果文件方便检查。写清洗逻辑前先用df.head()和df.info()充分了解数据内容。尽量不要修改原始数据而是生成新的 DataFrame。把所有数值提取逻辑统一放在一个函数中便于后期维护。比如在提取评分时可以在函数里加入校验def extract_score(rating_str): if not isinstance(rating_str, str): return None match re.search(r([\d.]), rating_str) return float(match.group(1)) if match else None这样做的好处是如果某一行数据格式异常返回的None会在后续分析中被 Pandas 忽略而不是直接报错中断整个流程。6.3 可视化部分可视化图表的信息密度很重要。画图时不要为了装饰而装饰每一处元素都应该有实际意义。建议注意以下几点标题要能说明图表的主要内容。坐标轴要标明单位。数据标签只加在关键点上避免所有数字堆在一起。颜色使用要有对比度方便打印和阅读。保存图片时设置适当 dpi一般 300 dpi 足够。6.4 文本分析部分字幕文本分析中停用词处理是一个关键点。所谓停用词就是像“的”“了”“是”“我”这类对主题分析没有实际帮助的词。可以在分词后过滤掉这些词stop_words {的, 了, 是, 在, 和, 我, 有, 就, 不, 都} words [w for w in words if w not in stop_words and len(w) 1 and w.isalpha()]更专业的做法是准备一个自定义停用词表文件运行时加载进去。这样处理后的词频结果才更接近电影的主题内容比如“蛇”“森林”“逃”等词就会出现在前面。7. 总结与下一步学习方向通过这一整套流程我从多个角度完整分析了《狂蟒之灾》系列电影先通过爬虫采集系列电影的基础信息再用 Pandas 清洗出规范的数据表然后用 Matplotlib 绘制评分走势和票房对比图最后用 jieba 和 wordcloud 对字幕文本做了词频分析。整个过程走下来不需要手动整理任何资料数据获取和处理都是由 Python 脚本自动完成。如果你想把这套能力再提升一个台阶可以往下面几个方向继续深入学习 Scrapy 框架构建更大规模的爬虫项目单机采集速度会提升不少而且自带去重和分布式扩展能力。学习 Flask 或 FastAPI把清洗后的电影数据制作成简单的 Web API方便自己或者团队随时查询。学习自动化报表生成将分析结果自动汇总成 PDF 或网页报告定时跑一次就能生成最新的影视数据报告。学习更高级的情感分析用训练好的模型对影评文本做情感分类从而判断观众对《狂蟒之灾》整体是好评还是差评。数据分析这条路重要的不是单纯记住某个函数而是建立“拿到问题 — 拆解步骤 — 用工具快速解决”的思维习惯。希望这篇文章提供的完整代码和排错经验能帮助你在自己的数据分析项目里少走弯路。如果你在复现过程中遇到其他问题欢迎在评论区留下你的报错信息和环境信息。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门