以下是一个基于Python的豆瓣电影TOP250爬虫项目案例,包含完整的技术原理说明、关键知识点解析和项目源代码。本案例采用面向对象编程思想,涵盖反爬机制处理、数据解析和存储等核心内容。
豆瓣电影TOP250爬虫项目
一、项目需求分析
- 目标网站:https://movie.douban.com/top250
- 爬取内容:
- 电影名称
- 导演和主演信息
- 上映年份
- 制片国家
- 电影类型
- 评分
- 评价人数
- 短评金句
- 技术挑战:
- 请求头验证
- 分页处理
- 频率限制
- 数据清洗
二、技术原理与知识点
1. 请求处理模块
import requests
from bs4 import BeautifulSoup
import time
import csv
class DoubanSpider:
def __init__(self):
self.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',
'Host': 'movie.douban.com'
}
self.base_url = 'https://movie.douban.com/top250?start={}&filter='
技术点解析:
- User-Agent伪装:模拟浏览器访问避免被识别为爬虫
- 分页URL构造:通过观察发现URL中start参数以25递增(0,25,50,…)
- 请求间隔:使用time.sleep()控制请求频率(防止触发反爬)
2. 页面解析模块
def parse_page(self, html):
soup = BeautifulSoup(html, 'lxml')
items = soup.find_all('div', class_='item')
for item in items:
# 电影基本信息解析
title = item.find('span', class_='title').text.strip()
year = item.find('div', class_='bd').find('br').next_sibling.strip()[:4]
countries_genre = item.find('div', class_='bd').p.contents[2].strip().split('/')
country = countries_genre[1].strip()
genre = countries_genre[2].strip()
details_url = item.find('div', class_='hd').find('a')['href']
# 评分信息解析
rating_num = item.find('span', class_='rating_num').text
rating_people = item.find('div', class_='star').contents[7].text[:-3]
# 短评金句解析
quote_tag = item.find('span', class_='inq')
quote = quote_tag.text if quote_tag else "无"
yield {
'title': title,
'year': year,
'country': country,
'genre': genre,
'details':details_url,
'rating': rating_num,
'votes': rating_people,
'quote': quote
}
技术点解析:
- BeautifulSoup定位元素:使用CSS选择器和DOM遍历
- 多层数据清洗:处理嵌套标签和空白字符
- 容错处理:对可能不存在的字段(如quote)进行判断
- 数据格式化:使用生成器yield返回结构化数据
3. 数据存储模块
def save_to_csv(self, data):
with open('douban_top250.csv', 'a', newline='', encoding='utf-8-sig') as f:
writer = csv.DictWriter(f, fieldnames=[
'title', 'year', 'country',
'genre', 'details', 'rating', 'votes', 'quote'
])
if f.tell() == 0:
writer.writeheader()
writer.writerow(data)
4. 主控制流程
def run(self):
for page in range(0, 250, 25):
url = self.base_url.format(page)
try:
response = requests.get(url, headers=self.headers, timeout=10)
if response.status_code == 200:
for data in self.parse_page(response.text):
self.save_to_csv(data)
print(f'成功爬取第{page//25+1}页数据')
else:
print(f'请求失败,状态码:{response.status_code}')
except Exception as e:
print(f'发生异常:{str(e)}')
time.sleep(1.5) # 控制爬取速度
if __name__ == '__main__':
spider = DoubanSpider()
spider.run()
三、反爬策略应对方案
- 请求头伪装:完整模拟浏览器headers
- 请求频率控制:每页间隔1.5秒
- IP代理池(扩展建议):
proxies = { 'http': 'http://12.34.56.78:8888', 'https': 'https://12.34.56.78:8888' } response = requests.get(url, headers=headers, proxies=proxies)
- 随机延迟(增强版):
import random time.sleep(random.uniform(1, 3))
四、项目运行结果
生成的CSV文件示例:
title,year,country,genre,details,rating,votes,quote
肖申克的救赎,1994,美国,犯罪 剧情,https://movie.douban.com/subject/1292052/,9.7,3126170,希望让人自由。
霸王别姬,1993,中国大陆 中国香港,剧情 爱情 同性,https://movie.douban.com/subject/1291546/,9.6,2306566,风华绝代。
泰坦尼克号,1997,美国 墨西哥,剧情 爱情 灾难,https://movie.douban.com/subject/1292722/,9.5,2367962,失去的才是永恒的。
阿甘正传,1994,美国,剧情 爱情,https://movie.douban.com/subject/1292720/,9.5,2325111,一部美国近现代史。
...
五、代码优化建议
- 使用Scrapy框架实现分布式爬虫
- 添加MySQL/MongoDB数据库存储
- 集成Selenium处理动态加载内容
- 实现断点续爬功能
- 添加日志记录系统
六、法律与道德考量
- 遵守robots.txt协议(豆瓣允许爬取但需控制频率)
- 不进行商业用途和恶意攻击
- 限制并发请求数量(建议单线程+合理延迟)
- 尊重网站的数据版权
完整项目代码已托管至gitcode:
https://gitcode.com/hzgnne/python-beginner/blob/main/%E7%88%AC%E8%99%AB/%E8%B1%86%E7%93%A3top250.py
通过这个项目案例,可以学习到:
- 完整的爬虫开发流程
- 网页解析技术的实际应用
- 反爬机制的应对策略
- 数据清洗与存储方案
- Python面向对象编程实践
建议在本地运行代码时根据实际情况调整请求间隔时间,并严格遵守相关法律法规。