1. 项目简介
本项目是一个面向初学者的 Python 爬虫实战项目,目标是爬取豆瓣电影 Top 250 榜单的数据,并将其保存为结构化的 CSV 文件。通过这个项目,你将学习到:
- 如何使用
requests库发送 HTTP 请求获取网页内容。 - 如何使用
BeautifulSoup库解析 HTML 并提取所需数据。 - 如何应对简单的反爬机制(如请求头设置)。
- 如何将爬取的数据进行清洗并保存到本地文件。
2. 环境准备
在开始之前,请确保你的电脑上已经安装了 Python(建议版本 3.7 或以上)。我们将使用 pip 来安装必要的第三方库。
打开终端或命令行,执行以下命令:
bash
pip install requests beautifulsoup4
安装完成后,可以创建一个新的 Python 文件,例如 douban_spider.py。
3. 分析目标网页
首先,我们需要分析豆瓣电影 Top 250 页面的结构,以确定如何定位我们需要的数据。
- 打开浏览器,访问 豆瓣电影 Top 250。
- 按
F12打开开发者工具,使用"检查元素"功能。 - 观察页面,我们发现每部电影信息都包含在一个
class="item"的div标签中。 - 我们需要提取的信息通常包括:
- 电影排名
- 电影名称
- 评分
- 评价人数
- 经典台词(引语)
4. 编写爬虫代码
下面我们将分步骤编写完整的爬虫代码。
4.1 导入库与定义基础变量
python
import requests
from bs4 import BeautifulSoup
import csv
import time
# 目标URL
base_url = 'https://movie.douban.com/top250'
# 定义请求头,模拟浏览器访问,应对基础反爬
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
}
# 用于存储所有电影信息的列表
all_movies = []
4.2 实现单页数据抓取函数
我们需要一个函数来处理单个页面的抓取和解析。
python
def scrape_page(url):
"""抓取并解析单个页面"""
try:
response = requests.get(url, headers=headers)
response.raise_for_status() # 检查请求是否成功
response.encoding = 'utf-8' # 设置编码
soup = BeautifulSoup(response.text, 'html.parser')
return soup
except requests.RequestException as e:
print(f"请求页面失败: {url}, 错误: {e}")
return None
4.3 实现数据解析函数
这个函数从解析好的 soup 对象中提取我们需要的数据。
这里是比较重要的一点,如果你们对于html网页结构不熟悉的话,可以设计一个代码以及一个专用与解析网页的智能体去生成代码,以此来防止解析时出现一些空结构。
python
def parse_movies(soup):
"""从页面中解析电影信息"""
movie_items = soup.find_all('div', class_='item')
page_movies = []
for item in movie_items:
# 电影排名
rank = item.find('em').get_text() if item.find('em') else 'N/A'
# 电影标题 (取第一个 title 属性)
title_tag = item.find('span', class_='title')
title = title_tag.get_text() if title_tag else 'N/A'
# 评分
rating_tag = item.find('span', class_='rating_num')
rating = rating_tag.get_text() if rating_tag else 'N/A'
# 评价人数 ------ 修复:先判断 star 容器是否存在
star_div = item.find('div', class_='star')
if star_div:
span_list = star_div.find_all('span')
if span_list:
comment_text = span_list[-1].get_text()
comment = comment_text[:-3] # 去掉"人评价"
else:
comment = '0'
else:
comment = '0'
# 经典台词(引语),可能不存在
quote_tag = item.find('span', class_='inq')
quote = quote_tag.get_text() if quote_tag else ''
movie_info = {
'排名': rank,
'标题': title,
'评分': rating,
'评价人数': comment,
'引语': quote
}
page_movies.append(movie_info)
# 打印进度
print(f"已抓取: {rank} {title}")
return page_movies
4.3 实现翻页与主循环
豆瓣 Top 250 有 10 页,我们需要循环处理每一页。
python
def main():
for page in range(0, 10): # 0-9 对应第1到第10页
start = page * 25
url = f'{base_url}?start={start}&filter='
print(f"正在抓取第 {page + 1} 页: {url}")
soup = scrape_page(url)
if not soup:
print(f"第 {page + 1} 页抓取失败,跳过。")
continue
movies = parse_movies(soup)
all_movies.extend(movies)
# 礼貌性延迟,避免请求过快
time.sleep(2)
print(f"所有页面抓取完成,共 {len(all_movies)} 条数据。")
4.4 实现数据保存函数
最后,我们将数据保存到 CSV 文件中。
python
def save_to_csv(movies, filename='douban_top250.csv'):
"""将电影列表保存为CSV文件"""
if not movies:
print("没有数据可保存。")
return
# 定义CSV文件的列名
fieldnames = ['排名', '标题', '评分', '评价人数', '引语']
try:
with open(filename, 'w', newline='', encoding='utf-8-sig') as csvfile:
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(movies)
print(f"数据已成功保存到 {filename}")
except IOError as e:
print(f"保存文件时出错: {e}")
4.5 完整代码与执行
将以上所有部分组合起来,并添加程序入口。
python
if __name__ == '__main__':
main()
save_to_csv(all_movies)
5. 运行与结果


-
将完整的代码保存到
douban_spider.py。 -
在终端中运行该脚本:
bashpython douban_spider.py -
程序将开始爬取,并在控制台打印进度。爬取完成后,会在当前目录下生成一个名为
douban_top250.csv的文件,你可以用 Excel 或文本编辑器打开查看数据。
6. 项目总结与扩展
恭喜!你已经完成了一个基础的网络爬虫项目。这个项目涵盖了爬虫的核心步骤:请求、解析、存储。
你可以尝试以下扩展练习来提升技能:
- 异常处理增强:为网络请求和文件操作添加更完善的异常处理。
- 数据清洗:清洗"评价人数"字段中的数字,并转换为整数类型。
- 存储到数据库 :尝试使用
sqlite3或pymysql将数据保存到数据库中。 - 爬取更多信息:尝试爬取每部电影的详情页链接,并进入详情页抓取导演、演员、类型等信息。
- 使用 Scrapy 框架:当项目变得复杂时,可以学习使用更专业的 Scrapy 框架来重写这个爬虫。
重要提醒 :爬虫应遵守网站的 robots.txt 协议,尊重网站版权,不要进行高频访问,避免对目标服务器造成压力。