Python 爬虫实战:豆瓣电影榜单与评分数据精准爬取
前言在大数据与数据分析快速发展的当下影视行业数据挖掘成为市场分析、用户偏好研究的核心手段豆瓣电影作为国内权威的影视评分平台其榜单数据、影片评分、演职员信息、用户评价等数据具备极高的分析价值。对于 Python 开发者而言爬取豆瓣电影公开数据是入门网络爬虫、掌握数据采集核心技能的经典实战项目既能夯实 HTTP 请求、网页解析、数据存储等基础能力又能理解反爬机制应对、数据结构化处理等进阶知识。本项目聚焦豆瓣电影TOP250 榜单、热映电影榜单、新上映电影榜单三大核心板块实现影片名称、上映年份、国家 / 地区、影片类型、评分、评价人数、导演、主演、剧情简介等全维度数据的自动化爬取、清洗与持久化存储。项目全程基于 Python 实现遵循合法合规爬取原则仅采集豆瓣公开非敏感数据严格遵守网站robots.txt协议与请求频率限制。本项目依赖的核心第三方库及官方文档链接如下读者可直接点击访问获取安装与使用指南RequestsHTTP 请求库官方文档BeautifulSoup4HTML/XML 解析库官方文档lxml高性能解析器官方文档pandas数据处理与存储库官方文档timePython 内置时间模块无需安装randomPython 内置随机数模块无需安装一、项目开发环境与前置准备1.1 开发环境要求本项目适配全平台操作系统Windows、macOS、Linux核心环境配置要求如下Python 版本3.8 及以上稳定版本推荐 3.9-3.11网络环境可正常访问豆瓣电影官网https://movie.douban.com/代码编辑器PyCharm、VS Code、Sublime 等任意 Python 开发工具1.2 核心依赖库安装豆瓣电影爬虫项目无需复杂的环境配置仅需通过pip命令安装第三方依赖库打开系统终端CMD、PowerShell、Terminal执行以下命令bash运行# 安装HTTP请求库 pip install requests # 安装网页解析库 pip install beautifulsoup4 lxml # 安装数据处理与存储库 pip install pandas安装完成后可通过pip list命令验证库是否安装成功确保无版本冲突问题。1.3 爬虫合法性与合规声明网络爬虫的使用必须遵守法律法规与网站规则本项目严格遵循以下合规要求仅爬取豆瓣电影公开可访问的非敏感数据不采集用户隐私、登录信息等涉密内容遵守豆瓣网站robots.txt协议https://movie.douban.com/robots.txt不爬取协议禁止的路径控制请求频率设置合理的请求间隔时间避免对豆瓣服务器造成流量压力爬取数据仅用于个人学习、数据分析研究不用于商业盈利、恶意竞争等非法用途。二、豆瓣电影网页结构分析爬虫的核心逻辑是模拟浏览器向目标网站发送 HTTP 请求获取网页源代码再通过解析规则提取目标数据因此网页结构分析是爬虫开发的核心前提。2.1 目标网页 URL 规则豆瓣电影三大核心榜单的 URL 具备固定规律无需动态拼接即可直接访问具体 URL 如下表所示表格榜单类型目标 URL分页规则豆瓣电影 TOP250https://movie.douban.com/top250start0、25、50...225共 10 页热映电影https://movie.douban.com/cinema/nowplaying/无分页单页展示全部热映影片新上映电影https://movie.douban.com/cinema/upcoming/无分页单页展示全部新片其中豆瓣电影 TOP250 榜单采用分页展示每页显示 25 部影片总页数为 10 页分页参数start为偏移量通过修改start数值即可遍历全部榜单数据。2.2 网页 HTML 结构解析以豆瓣电影 TOP250 榜单为例通过浏览器开发者工具F12查看网页源代码核心数据结构如下所有影片数据包裹在 class 为article的 div 标签内单部影片数据包裹在 class 为item的 div 标签内影片核心信息层级影片排名class 为pic的 div 标签内的 em 标签影片海报链接class 为pic的 div 标签内的 img 标签src属性影片详情页链接class 为hd的 div 标签内的 a 标签href属性影片名称class 为hd的 div 标签内的 span 标签上映年份 / 地区 / 类型class 为bd的 div 标签内的 p 标签第一段文本影片评分class 为rating_num的 span 标签文本评价人数class 为star的 span 标签最后一段文本剧情简介class 为inq的 span 标签文本部分影片无简介热映电影与新上映电影的网页结构与 TOP250 榜单高度相似仅标签 class 名称存在细微差异解析逻辑可通用。2.3 反爬机制识别豆瓣电影针对爬虫具备基础的反爬机制主要包括请求头验证检测请求是否为浏览器发起非浏览器请求直接拒绝请求频率限制短时间内高频请求会触发 IP 封禁、页面重定向动态加载验证部分数据采用静态加载无 JS 动态渲染无需使用 Selenium 等工具。针对以上反爬机制本项目通过伪造请求头、设置随机请求间隔即可轻松绕过无需复杂的反爬应对方案。三、豆瓣电影爬虫核心代码实现本项目采用模块化开发思想将爬虫拆分为请求发送、网页解析、数据存储三大核心模块代码具备高可读性、可扩展性便于后续维护与功能升级。3.1 模块导入与全局配置首先导入项目所需的所有库定义全局常量请求头、基础 URL、存储路径等统一管理配置信息降低代码耦合度。python运行# 导入第三方依赖库 import requests from bs4 import BeautifulSoup import pandas as pd import time import random # 全局配置伪造浏览器请求头绕过请求头验证 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, Accept: text/html,application/xhtmlxml,application/xml;q0.9,image/webp,*/*;q0.8, Accept-Language: zh-CN,zh;q0.9, Connection: close } # 全局配置豆瓣电影三大榜单基础URL BASE_URLS { top250: https://movie.douban.com/top250?start{}filter, nowplaying: https://movie.douban.com/cinema/nowplaying/, upcoming: https://movie.douban.com/cinema/upcoming/ } # 全局配置数据存储路径 SAVE_PATH 豆瓣电影数据.csv # 全局配置请求间隔时间秒随机间隔避免固定频率 MIN_SLEEP 1 MAX_SLEEP 3代码原理User-Agent是请求头的核心参数伪造浏览器的 UA 信息让服务器认为请求是合法浏览器发起绕过基础请求验证全局常量统一配置便于后续修改 URL、请求头、存储路径等信息无需逐行修改代码随机请求间隔MIN_SLEEP和MAX_SLEEP避免固定频率请求触发反爬机制。3.2 HTTP 请求发送模块该模块负责向目标 URL 发送 GET 请求获取网页源代码具备异常处理能力应对网络超时、连接失败、请求错误等问题。python运行def get_html_content(url: str) - str: 发送HTTP GET请求获取网页源代码 :param url: 目标网页URL :return: 网页源代码字符串请求失败返回空字符串 try: # 发送GET请求设置超时时间为10秒 response requests.get(url, headersHEADERS, timeout10) # 判断请求是否成功状态码200表示成功 if response.status_code 200: # 设置网页编码为utf-8避免中文乱码 response.encoding utf-8 return response.text else: print(f请求失败状态码{response.status_code}URL{url}) return except requests.exceptions.RequestException as e: print(f请求发生异常{str(e)}URL{url}) return 代码原理函数采用类型注解明确参数与返回值类型提升代码可读性与可维护性requests.get()方法发送 GET 请求传入headers伪造浏览器timeout防止请求无限等待通过response.status_code判断请求状态HTTP 200 为成功状态码response.encoding utf-8强制设置编码格式解决中文乱码问题捕获所有RequestException异常覆盖网络超时、连接失败、DNS 错误等所有请求异常避免程序崩溃。3.3 网页数据解析模块该模块是爬虫的核心通过 BeautifulSoup4 解析网页源代码提取目标数据针对不同榜单分别实现解析逻辑。3.3.1 豆瓣电影 TOP250 榜单解析python运行def parse_top250(html: str) - list: 解析豆瓣电影TOP250网页源代码提取影片数据 :param html: 网页源代码字符串 :return: 影片数据列表每个元素为字典存储单部影片信息 # 初始化数据列表 movie_list [] # 创建BeautifulSoup解析对象使用lxml解析器高性能 soup BeautifulSoup(html, lxml) # 查找所有影片item标签 movie_items soup.find_all(div, class_item) # 遍历每个影片标签提取数据 for item in movie_items: movie_data {} # 提取影片排名 movie_data[排名] item.find(em).get_text(stripTrue) # 提取影片名称 title_tags item.find(div, class_hd).find_all(span) movie_data[影片名称] .join([tag.get_text(stripTrue) for tag in title_tags]) # 提取影片详情页链接 movie_data[详情链接] item.find(div, class_hd).find(a)[href] # 提取上映年份、国家/地区、影片类型 info_text item.find(div, class_bd).p.get_text(stripTrue) # 分割字符串拆分年份、地区、类型 info_list info_text.split(\xa0/\xa0) if len(info_list) 3: movie_data[上映年份] info_list[0] movie_data[制片国家/地区] info_list[1] movie_data[影片类型] info_list[2] else: movie_data[上映年份] movie_data[制片国家/地区] movie_data[影片类型] # 提取影片评分 movie_data[豆瓣评分] item.find(span, class_rating_num).get_text(stripTrue) # 提取评价人数 star_text item.find(div, class_star).get_text(stripTrue) movie_data[评价人数] star_text.replace(人评价, ) # 提取剧情简介部分影片无简介做异常处理 quote_tag item.find(span, class_inq) movie_data[剧情简介] quote_tag.get_text(stripTrue) if quote_tag else 无简介 # 将单部影片数据添加到列表 movie_list.append(movie_data) return movie_list代码原理BeautifulSoup(html, lxml)创建解析对象lxml是高性能解析器解析速度远高于内置解析器find_all()方法查找所有符合条件的标签find()方法查找单个标签class_参数指定标签类名避免与 Python 关键字class冲突get_text(stripTrue)提取标签文本内容stripTrue去除文本前后的空格、换行符等无用字符字符串分割split(\xa0/\xa0)网页中年份、地区、类型通过/分隔\xa0是网页中的不间断空格必须以此为分隔符才能正确拆分异常处理针对无剧情简介的影片通过三元表达式赋值为「无简介」避免程序报错。3.3.2 热映电影与新上映电影解析python运行def parse_nowplaying_upcoming(html: str, movie_type: str) - list: 解析热映电影/新上映电影网页源代码提取影片数据 :param html: 网页源代码字符串 :param movie_type: 影片类型热映/新上映 :return: 影片数据列表 movie_list [] soup BeautifulSoup(html, lxml) # 查找所有影片标签 movie_items soup.find_all(li, class_poster-item) for item in movie_items: movie_data {} movie_data[影片类型] movie_type # 提取影片名称 movie_data[影片名称] item.find(img)[alt] # 提取影片详情页链接 movie_data[详情链接] https://movie.douban.com item.find(a)[href] # 提取影片海报链接 movie_data[海报链接] item.find(img)[src] # 提取评分部分影片无评分做异常处理 score_tag item.find(p, class_score) movie_data[豆瓣评分] score_tag.get_text(stripTrue) if score_tag else 暂无评分 movie_list.append(movie_data) return movie_list代码原理热映与新上映电影网页结构一致共用一个解析函数通过movie_type参数区分影片类型影片详情页链接为相对路径需拼接豆瓣电影基础域名https://movie.douban.com生成完整链接针对未上映无评分的影片赋值为「暂无评分」保证数据完整性。3.4 数据存储模块该模块将解析后的结构化数据保存为 CSV 格式文件CSV 文件通用性强可直接用 Excel、WPS、数据库、数据分析工具打开便于后续数据处理与分析。python运行def save_movie_data(data_list: list, save_path: str) - None: 将影片数据保存为CSV文件 :param data_list: 影片数据总列表 :param save_path: 文件保存路径 # 创建DataFrame对象pandas核心数据结构结构化存储数据 df pd.DataFrame(data_list) # 保存为CSV文件编码为utf-8-sig避免Excel打开中文乱码不保存索引列 df.to_csv(save_path, indexFalse, encodingutf-8-sig) print(f数据保存成功共爬取{len(data_list)}部影片文件路径{save_path})代码原理pandas.DataFrame()将列表字典转换为结构化的表格数据自动匹配字段名与数据to_csv()方法保存为 CSV 文件indexFalse取消默认索引列encodingutf-8-sig解决 Excel 打开中文乱码问题Windows 系统专属打印保存结果直观展示爬取数据量与文件路径便于用户验证。3.5 主函数爬虫调度核心主函数负责调度三大模块实现分页遍历、数据拼接、爬虫执行、间隔等待的全流程逻辑是爬虫的入口函数。python运行def main(movie_type: str top250) - None: 爬虫主函数调度请求、解析、存储模块执行爬虫任务 :param movie_type: 爬取类型top250/nowplaying/upcoming # 初始化总数据列表 total_movie_data [] print(f开始爬取豆瓣电影【{movie_type}】数据...) # 根据类型执行不同爬取逻辑 if movie_type top250: # TOP250榜单遍历10页数据 for page in range(10): start page * 25 url BASE_URLS[top250].format(start) print(f正在爬取第{page1}页URL{url}) # 获取网页源代码 html get_html_content(url) if not html: print(f第{page1}页请求失败跳过该页) continue # 解析数据 page_data parse_top250(html) # 拼接数据 total_movie_data.extend(page_data) # 随机间隔时间避免高频请求 sleep_time random.randint(MIN_SLEEP, MAX_SLEEP) time.sleep(sleep_time) elif movie_type nowplaying: # 热映电影单页爬取 html get_html_content(BASE_URLS[nowplaying]) if html: page_data parse_nowplaying_upcoming(html, 热映电影) total_movie_data.extend(page_data) elif movie_type upcoming: # 新上映电影单页爬取 html get_html_content(BASE_URLS[upcoming]) if html: page_data parse_nowplaying_upcoming(html, 新上映电影) total_movie_data.extend(page_data) else: print(输入的爬取类型错误请输入top250/nowplaying/upcoming) return # 保存数据 if total_movie_data: save_movie_data(total_movie_data, SAVE_PATH) else: print(未爬取到任何数据) # 程序入口执行爬虫 if __name__ __main__: # 可选参数top250豆瓣TOP250、nowplaying热映、upcoming新上映 main(movie_typetop250)代码原理主函数通过movie_type参数控制爬取的榜单类型支持三种榜单自由切换TOP250 榜单通过for循环遍历 10 页每页计算start偏移量拼接分页 URL每爬取一页数据后执行random.randint()生成随机等待时间time.sleep()暂停程序控制请求频率total_movie_data.extend()将每页数据拼接为总数据列表最终统一保存if __name__ __main__是 Python 程序入口规范确保函数仅在直接运行时执行。四、爬虫运行与结果验证4.1 爬虫运行方法将完整代码复制到 Python 编辑器中保存为douban_movie_spider.py文件修改主函数中main(movie_typetop250)的参数切换需要爬取的榜单运行代码终端会实时打印爬取进度、页码、URL 等信息爬取完成后会在代码同级目录生成豆瓣电影数据.csv文件。4.2 运行结果示例以爬取豆瓣电影 TOP250 榜单为例终端输出如下plaintext开始爬取豆瓣电影【top250】数据... 正在爬取第1页URLhttps://movie.douban.com/top250?start0filter 正在爬取第2页URLhttps://movie.douban.com/top250?start25filter ... 正在爬取第10页URLhttps://movie.douban.com/top250?start225filter 数据保存成功共爬取250部影片文件路径豆瓣电影数据.csv4.3 数据结果展示生成的 CSV 文件包含结构化数据以 TOP250 榜单为例核心字段如下表所示表格排名影片名称详情链接上映年份制片国家 / 地区影片类型豆瓣评分评价人数剧情简介1肖申克的救赎https://movie.douban.com/subject/1292054/1994美国犯罪 剧情9.72908562希望让人自由2霸王别姬https://movie.douban.com/subject/1291546/1993中国大陆 中国香港剧情 爱情 同性9.62145628风华绝代一入霸王别姬...........................数据完整无缺失、无乱码可直接用于数据分析、可视化展示等后续操作。五、爬虫优化与进阶扩展5.1 基础优化方案多线程 / 多进程优化当前爬虫为单线程爬取速度较慢可通过threading、multiprocessing库实现多线程爬取提升效率需严格控制线程数避免触发反爬IP 代理池若大规模爬取触发 IP 封禁可搭建 IP 代理池通过代理 IP 发送请求绕过 IP 限制日志记录使用logging库替代print函数记录爬虫运行日志、异常信息便于问题排查增量爬取记录已爬取的影片 ID仅爬取新增数据避免重复爬取提升效率。5.2 功能扩展方向深度爬取详情页基于影片详情链接爬取演职员表、用户影评、剧照、票房等更详细的数据数据清洗与去重增加数据清洗逻辑去除重复数据、异常数据提升数据质量多格式存储支持将数据保存为 Excel、JSON、MySQL 数据库、SQLite 等格式定时爬取结合schedule库实现定时自动化爬取每日 / 每周自动更新电影数据数据可视化结合matplotlib、pyecharts库将爬取数据生成评分分布图、类型占比图等可视化图表。六、常见问题与解决方案6.1 中文乱码问题问题现象生成的 CSV 文件用 Excel 打开后中文显示为乱码解决方案保存文件时指定编码为utf-8-sig代码中已实现该配置无需修改。6.2 请求失败 / 被封禁 IP问题现象终端提示请求失败或网页返回 403/404 状态码解决方案增大请求间隔时间将MIN_SLEEP和MAX_SLEEP调整为 3-5 秒更换User-Agent请求头检查网络是否可正常访问豆瓣电影官网。6.3 解析不到数据问题现象程序运行正常但未爬取到任何数据解决方案检查网页结构是否发生变化豆瓣可能会修改标签 class 名需同步更新解析规则确认 URL 是否正确避免拼写错误检查请求头是否设置正确未设置请求头会导致返回空白页面。6.4 依赖库安装失败问题现象执行pip install命令时提示安装错误解决方案切换国内镜像源清华源、阿里源加速安装pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests升级 pip 版本python -m pip install --upgrade pip确认 Python 环境是否正确避免多版本冲突。七、项目总结与学习价值本项目完整实现了豆瓣电影三大核心榜单数据的自动化爬取覆盖环境配置、网页分析、代码编写、数据存储、问题排查全流程是 Python 爬虫入门的经典实战项目。从技术层面来看项目涵盖了网络请求、网页解析、数据结构化处理、异常处理、反爬机制应对等爬虫核心技能代码采用模块化设计具备高可读性、可扩展性适合初学者学习与二次开发。从应用价值来看爬取的豆瓣电影数据可用于影视行业数据分析、用户偏好研究、评分预测、推荐系统搭建等场景为数据分析、人工智能等领域的学习提供数据支撑。学习本项目后可快速掌握静态网页爬虫的开发逻辑具备独立开发电商、图书、招聘等领域静态网页爬虫的能力为后续学习动态网页爬虫、分布式爬虫、大数据采集等进阶知识奠定坚实基础。