Python 爬虫实战:抓取豆瓣电影 Top 250
网络爬虫是数据采集的重要工具。本文将通过抓取豆瓣电影 Top 250 的实战案例,带你入门 Python 爬虫开发。
准备工作
安装依赖
bash
pip install requests beautifulsoup4 lxml
目标分析
豆瓣电影 Top 250 的 URL 结构:
- 第 1 页:
https://movie.douban.com/top250?start=0 - 第 2 页:
https://movie.douban.com/top250?start=25 - 第 n 页:
https://movie.douban.com/top250?start={(n-1)*25}
基础爬虫代码
python
import requests
from bs4 import BeautifulSoup
import time
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
def get_movies(start):
url = f'https://movie.douban.com/top250?start={start}'
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'lxml')
movies = []
items = soup.find_all('div', class_='item')
for item in items:
movie = {
'rank': item.find('em').text,
'title': item.find('span', class_='title').text,
'rating': item.find('span', class_='rating_num').text,
'quote': item.find('span', class_='inq').text if item.find('span', class_='inq') else ''
}
movies.append(movie)
return movies
# 抓取所有 250 部电影
all_movies = []
for i in range(0, 250, 25):
print(f'正在抓取第 {i//25 + 1} 页...')
movies = get_movies(i)
all_movies.extend(movies)
time.sleep(1) # 礼貌地等待 1 秒
# 保存结果
import json
with open('douban_top250.json', 'w', encoding='utf-8') as f:
json.dump(all_movies, f, ensure_ascii=False, indent=2)
print(f'共抓取 {len(all_movies)} 部电影')
数据存储到数据库
python
import sqlite3
# 创建数据库连接
conn = sqlite3.connect('movies.db')
cursor = conn.cursor()
# 创建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS movies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
rank INTEGER,
title TEXT,
rating REAL,
quote TEXT
)
''')
# 插入数据
for movie in all_movies:
cursor.execute('''
INSERT INTO movies (rank, title, rating, quote)
VALUES (?, ?, ?, ?)
''', (movie['rank'], movie['title'], float(movie['rating']), movie['quote']))
conn.commit()
conn.close()
数据可视化
python
import matplotlib.pyplot as plt
import pandas as pd
# 读取数据
df = pd.read_json('douban_top250.json')
# 评分分布
plt.figure(figsize=(10, 6))
plt.hist(df['rating'], bins=20, edgecolor='black')
plt.xlabel('评分')
plt.ylabel('电影数量')
plt.title('豆瓣 Top 250 电影评分分布')
plt.savefig('rating_distribution.png')
plt.show()
爬虫注意事项
1. 遵守 Robots 协议
python
import urllib.robotparser
rp = urllib.robotparser.RobotFileParser()
rp.set_url('https://movie.douban.com/robots.txt')
rp.read()
# 检查是否可以抓取
if rp.can_fetch('*', 'https://movie.douban.com/top250'):
print('可以抓取')
2. 控制请求频率
python
import random
# 随机延迟,模拟人类行为
time.sleep(random.uniform(1, 3))
3. 使用代理池
python
proxies = [
{'http': 'http://proxy1.com:8080'},
{'http': 'http://proxy2.com:8080'},
]
response = requests.get(url, headers=headers, proxies=random.choice(proxies))
4. 处理反爬机制
python
# 使用 Session 保持 cookies
session = requests.Session()
# 添加更多请求头
headers = {
'User-Agent': 'Mozilla/5.0...',
'Accept': 'text/html,application/xhtml+xml...',
'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
'Referer': 'https://movie.douban.com/'
}
进阶:使用 Scrapy 框架
对于大型爬虫项目,推荐使用 Scrapy:
python
# douban_spider.py
import scrapy
class DoubanSpider(scrapy.Spider):
name = 'douban'
allowed_domains = ['movie.douban.com']
start_urls = ['https://movie.douban.com/top250']
def parse(self, response):
for item in response.css('div.item'):
yield {
'rank': item.css('em::text').get(),
'title': item.css('span.title::text').get(),
'rating': item.css('span.rating_num::text').get(),
}
# 翻页
next_page = response.css('span.next a::attr(href)').get()
if next_page:
yield response.follow(next_page, self.parse)
运行:
bash
scrapy crawl douban -o movies.json
总结
爬虫开发需要注意:
- 遵守规则:尊重网站的 Robots 协议
- 控制频率:不要给服务器造成压力
- 数据清洗:抓取的数据需要清洗和验证
- 异常处理:网络请求可能失败,需要重试机制
希望这篇文章能帮助你入门 Python 爬虫!
标签: #Python #爬虫 #数据分析 #编程教程
发布时间: 2026年3月18日
觉得有用就点个赞吧~