实战:爬取豆瓣电影Top250,并生成Excel榜单
豆瓣电影 Top250 汇集了全球优质影片,手动整理榜单耗时费力。本文将通过 Python 实现自动化爬取,提取电影关键信息并生成 Excel 榜单,全程贴合实战场景,新手也能轻松跟随操作。
一、环境与工具准备
1. 核心工具
- Python 环境:推荐 3.8 及以上版本(确保环境变量配置正确)。
- 必备库:
requests
:发送 HTTP 请求,获取网页数据;BeautifulSoup4
:解析 HTML 页面,提取目标信息;pandas
:处理结构化数据,生成 Excel 文件;openpyxl
:作为 Excel 写入引擎,支持格式优化。
2. 库安装命令
打开命令提示符(Windows)或终端(Mac/Linux),执行以下命令安装依赖:
bash
pip install requests beautifulsoup4 pandas openpyxl
二、爬取逻辑分析
豆瓣电影 Top250 共 10 页,每页 25 部影片,页面 URL 规律为:https://movie.douban.com/top250?start=0&filter=
(start
参数从 0 开始,每页递增 25,如第 2 页为start=25
,第 10 页为start=225
)。
需提取的电影信息包括:电影名称、评分、评价人数、导演及主演、上映时间、制片国家 / 地区、影片类型。
三、分步实现爬取
1. 定义爬取函数(获取单页数据)
首先编写函数get_movie_data
,实现 “发送请求→解析页面→提取数据” 的流程,同时添加反爬处理(设置请求头模拟浏览器):
python
运行
import requests
from bs4 import BeautifulSoup
import pandas as pd
import timedef get_movie_data(page_start):# 1. 设置请求头,避免被豆瓣反爬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"}# 2. 构造当前页URLurl = f"https://movie.douban.com/top250?start={page_start}&filter="# 3. 发送GET请求,获取网页内容response = requests.get(url, headers=headers)response.encoding = "utf-8" # 解决中文乱码soup = BeautifulSoup(response.text, "html.parser") # 解析HTML# 4. 提取当前页所有电影项(共25个)movie_list = soup.find_all("div", class_="item")page_data = [] # 存储当前页电影数据for movie in movie_list:# 提取电影名称(中文名称)name = movie.find("span", class_="title").text# 提取评分score = movie.find("span", class_="rating_num").text# 提取评价人数(处理格式,如“123.4万”→“1234000”)comment_num = movie.find("div", class_="star").find_all("span")[-1].textif "万" in comment_num:comment_num = int(float(comment_num.replace("人评价", "").replace("万", "")) * 10000)else:comment_num = int(comment_num.replace("人评价", ""))# 提取导演、主演、上映时间、国家、类型(信息在同一标签中,需分割处理)info = movie.find("div", class_="bd").find("p", class_="").text.strip().split("\n")# 处理导演和主演(第一行信息)director_actor = info[0].strip().replace("\xa0", "").replace("导演: ", "").split("主演: ")director = director_actor[0] # 导演actor = director_actor[1] if len(director_actor) > 1 else "暂无" # 主演(避免无主演情况报错)# 处理上映时间、国家、类型(第二行信息)year_area_genre = info[1].strip().split("\xa0/\xa0")year = year_area_genre[0] # 上映时间area = year_area_genre[1] # 制片国家/地区genre = year_area_genre[2] # 影片类型# 将单部电影数据存入列表page_data.append([name, score, comment_num, director, actor, year, area, genre])return page_data
2. 批量爬取 10 页数据
通过循环遍历start
参数(0、25、50...225),批量获取所有 250 部电影数据,并整合到总列表中:
python
运行
def crawl_all_movies():all_movie_data = [] # 存储所有电影数据# 循环爬取10页(start从0到225,步长25)for page_start in range(0, 250, 25):print(f"正在爬取第{page_start//25 + 1}页...")page_data = get_movie_data(page_start)all_movie_data.extend(page_data) # 追加当前页数据到总列表time.sleep(1) # 间隔1秒,降低反爬风险print("爬取完成!共获取250部电影数据。")return all_movie_data# 执行爬取
movie_data = crawl_all_movies()
四、生成 Excel 榜单
利用pandas
将爬取到的列表数据转换为 DataFrame,再写入 Excel 文件,同时优化表格格式(调整列宽):
python
运行
def generate_excel(movie_data, excel_path="豆瓣电影Top250榜单.xlsx"):# 1. 定义Excel列名columns = ["电影名称", "评分", "评价人数", "导演", "主演", "上映时间", "制片国家/地区", "影片类型"]# 2. 转换为DataFramedf = pd.DataFrame(movie_data, columns=columns)# 3. 写入Excel(使用openpyxl引擎)with pd.ExcelWriter(excel_path, engine="openpyxl") as writer:df.to_excel(writer, sheet_name="Top250", index=False) # index=False不保留行号# 4. 优化列宽(获取工作表对象)worksheet = writer.sheets["Top250"]# 为每列设置合适宽度(根据列名和内容长度调整)column_widths = [15, 8, 12, 25, 35, 12, 15, 15]for i, width in enumerate(column_widths, 1): # i从1开始(Excel列号从A=1开始)worksheet.column_dimensions[chr(64 + i)].width = widthprint(f"Excel榜单已生成:{excel_path}")# 执行Excel生成
generate_excel(movie_data)
五、完整代码与运行说明
1. 完整代码整合
将上述步骤整合为完整脚本,直接运行即可:
python
运行
import requests
from bs4 import BeautifulSoup
import pandas as pd
import timedef get_movie_data(page_start):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"}url = f"https://movie.douban.com/top250?start={page_start}&filter="response = requests.get(url, headers=headers)response.encoding = "utf-8"soup = BeautifulSoup(response.text, "html.parser")movie_list = soup.find_all("div", class_="item")page_data = []for movie in movie_list:name = movie.find("span", class_="title").textscore = movie.find("span", class_="rating_num").textcomment_num = movie.find("div", class_="star").find_all("span")[-1].textif "万" in comment_num:comment_num = int(float(comment_num.replace("人评价", "").replace("万", "")) * 10000)else:comment_num = int(comment_num.replace("人评价", ""))info = movie.find("div", class_="bd").find("p", class_="").text.strip().split("\n")director_actor = info[0].strip().replace("\xa0", "").split("主演: ")director = director_actor[0]actor = director_actor[1] if len(director_actor) > 1 else "暂无"year_area_genre = info[1].strip().split("\xa0/\xa0")year = year_area_genre[0]area = year_area_genre[1]genre = year_area_genre[2]page_data.append([name, score, comment_num, director, actor, year, area, genre])return page_datadef crawl_all_movies():all_movie_data = []for page_start in range(0, 250, 25):print(f"正在爬取第{page_start//25 + 1}页...")page_data = get_movie_data(page_start)all_movie_data.extend(page_data)time.sleep(1)print("爬取完成!共获取250部电影数据。")return all_movie_datadef generate_excel(movie_data, excel_path="豆瓣电影Top250榜单.xlsx"):columns = ["电影名称", "评分", "评价人数", "导演", "主演", "上映时间", "制片国家/地区", "影片类型"]df = pd.DataFrame(movie_data, columns=columns)with pd.ExcelWriter(excel_path, engine="openpyxl") as writer:df.to_excel(writer, sheet_name="Top250", index=False)worksheet = writer.sheets["Top250"]column_widths = [15, 8, 12, 25, 35, 12, 15, 15]for i, width in enumerate(column_widths, 1):worksheet.column_dimensions[chr(64 + i)].width = widthprint(f"Excel榜单已生成:{excel_path}")if __name__ == "__main__":movie_data = crawl_all_movies()generate_excel(movie_data)
2. 运行说明
- 运行脚本后,控制台会显示爬取进度(如 “正在爬取第 1 页...”);
- 爬取完成后,会在脚本所在目录生成 “豆瓣电影 Top250 榜单.xlsx”;
- 打开 Excel 可看到结构化数据,列宽已优化,可直接用于统计或分享。
六、注意事项
- 反爬风险:若频繁爬取导致 IP 被限制,可更换
User-Agent
(从浏览器开发者工具中获取),或增加time.sleep
间隔(如 2-3 秒); - 页面更新:若豆瓣调整页面 HTML 结构,需重新分析标签(如
class
属性),修改get_movie_data
中的解析逻辑; - 合规性:本爬取仅用于个人学习,请勿用于商业用途,遵守豆瓣《网站服务条款》。
通过以上步骤,我们实现了从数据爬取到 Excel 生成的全流程自动化。若需扩展功能(如按评分筛选、添加电影海报链接),可在现有代码基础上进一步优化,欢迎根据需求探索更多可能性。
文章已涵盖爬取与生成 Excel 的完整实战流程。若你对代码优化(如增加数据筛选功能)、格式调整(如 Excel 颜色美化)有需求,或在实操中遇到问题,都可以随时告诉我。