1. 项目概述
今天我要分享的是一个Python爬虫实战项目——抓取豆瓣Top 250电影数据。这个项目非常适合爬虫初学者,因为它涵盖了爬虫开发的核心流程:请求发送、页面解析和数据存储。通过这个项目,你不仅能掌握基础爬虫技能,还能获得一份有价值的电影数据集。
2. 环境准备
2.1 安装必要库
首先确保你的Python环境是3.6及以上版本。我们需要安装以下库:
pip install requests beautifulsoup4 pandas- requests:用于发送HTTP请求
- beautifulsoup4:用于解析HTML页面
- pandas:用于数据存储和处理
2.2 代理设置
为了避免被封IP,建议设置请求间隔:
import time import random def random_sleep(): time.sleep(random.uniform(1, 3))3. 爬虫实现
3.1 分析页面结构
豆瓣Top250的URL是:https://movie.douban.com/top250
通过浏览器开发者工具查看页面结构,发现:
- 每页显示25部电影
- 电影信息包含在class为"item"的div中
- 电影名称在class为"title"的span中
- 评分在class为"rating_num"的span中
3.2 请求页面
import requests from bs4 import BeautifulSoup def get_page(url): 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' } try: response = requests.get(url, headers=headers) response.raise_for_status() return response.text except requests.exceptions.RequestException as e: print(f"请求失败: {e}") return None3.3 解析数据
def parse_page(html): soup = BeautifulSoup(html, 'html.parser') items = soup.find_all('div', class_='item') movies = [] for item in items: title = item.find('span', class_='title').text rating = item.find('span', class_='rating_num').text movies.append({'title': title, 'rating': rating}) return movies3.4 分页处理
豆瓣Top250共有10页,每页25部电影:
def crawl_top250(): base_url = "https://movie.douban.com/top250?start={}" all_movies = [] for i in range(0, 250, 25): url = base_url.format(i) html = get_page(url) if html: movies = parse_page(html) all_movies.extend(movies) random_sleep() return all_movies4. 数据存储
4.1 保存为CSV
import pandas as pd def save_to_csv(movies, filename='douban_top250.csv'): df = pd.DataFrame(movies) df.to_csv(filename, index=False, encoding='utf_8_sig')4.2 保存为Excel
def save_to_excel(movies, filename='douban_top250.xlsx'): df = pd.DataFrame(movies) df.to_excel(filename, index=False)5. 完整代码
import requests from bs4 import BeautifulSoup import pandas as pd import time import random def random_sleep(): time.sleep(random.uniform(1, 3)) def get_page(url): 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' } try: response = requests.get(url, headers=headers) response.raise_for_status() return response.text except requests.exceptions.RequestException as e: print(f"请求失败: {e}") return None def parse_page(html): soup = BeautifulSoup(html, 'html.parser') items = soup.find_all('div', class_='item') movies = [] for item in items: title = item.find('span', class_='title').text rating = item.find('span', class_='rating_num').text movies.append({'title': title, 'rating': rating}) return movies def crawl_top250(): base_url = "https://movie.douban.com/top250?start={}" all_movies = [] for i in range(0, 250, 25): url = base_url.format(i) html = get_page(url) if html: movies = parse_page(html) all_movies.extend(movies) random_sleep() return all_movies def save_to_csv(movies, filename='douban_top250.csv'): df = pd.DataFrame(movies) df.to_csv(filename, index=False, encoding='utf_8_sig') if __name__ == '__main__': movies = crawl_top250() save_to_csv(movies) print(f"成功爬取{len(movies)}部电影数据")6. 常见问题
6.1 被封IP怎么办?
- 设置合理的请求间隔
- 使用代理IP池
- 更换User-Agent
6.2 数据不完整
检查页面结构是否变化,可能需要更新解析逻辑。
6.3 编码问题
确保保存文件时使用utf_8_sig编码,避免中文乱码。
7. 进阶优化
7.1 多线程爬取
from concurrent.futures import ThreadPoolExecutor def crawl_page(start): url = f"https://movie.douban.com/top250?start={start}" html = get_page(url) if html: return parse_page(html) return [] def crawl_top250_multi(): with ThreadPoolExecutor(max_workers=5) as executor: results = executor.map(crawl_page, range(0, 250, 25)) return [movie for result in results if result for movie in result]7.2 获取更多字段
可以扩展解析函数,获取导演、主演、上映年份等信息:
def parse_page_extended(html): soup = BeautifulSoup(html, 'html.parser') items = soup.find_all('div', class_='item') movies = [] for item in items: title = item.find('span', class_='title').text rating = item.find('span', class_='rating_num').text info = item.find('div', class_='bd').p.get_text(strip=True) movies.append({ 'title': title, 'rating': rating, 'info': info }) return movies8. 总结
这个项目展示了Python爬虫的基本流程,从请求发送到数据解析再到存储。通过这个案例,你可以掌握:
- requests库的基本使用
- BeautifulSoup解析HTML
- 分页爬取技巧
- 数据存储方法
在实际项目中,还需要考虑反爬机制、数据清洗等问题。建议先从简单的项目开始,逐步深入。