
豆瓣电影TOP 250榜单爬虫教程
在本教程中,我们将学习如何使用Python编写一个爬虫程序来爬取豆瓣电影TOP 250榜单的数据。我们将使用requests库来发送HTTP请求,BeautifulSoup库来解析HTML页面,以及openpyxl库来将爬取的数据保存到Excel文件中。
环境准备
确保你已经安装了以下Python库,如果没有安装,可以使用pip进行安装:
pip install requests beautifulsoup4 openpyxl
爬虫代码
import requests
from bs4 import BeautifulSoup
from openpyxl import Workbook
from openpyxl.drawing.image import Image as openpyxl_Image
from io import BytesIO
# 模拟浏览器的请求头部
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'
}
# 创建工作簿和工作表
wb = Workbook()
ws = wb.active
ws.title = "Douban Top 250"
# 设置列宽
ws.column_dimensions['A'].width = 10
ws.column_dimensions['B'].width = 25
ws.column_dimensions['C'].width = 10
ws.column_dimensions['D'].width = 20
ws.column_dimensions['E'].width = 20
ws.column_dimensions['F'].width = 10
ws.column_dimensions['G'].width = 50
ws.column_dimensions['H'].width = 20 # 设置图片列的宽度
# 添加标题行
ws.append(["排名", "标题", "年份", "国家", "类型", "评分", "简介", "图片"])
# 豆瓣电影Top 250共有10页
for page_num in range(10):
start = page_num * 25
url = f"https://movie.douban.com/top250?start={start}&filter="
response = requests.get(url, headers=headers)
if response.status_code == 200:
soup = BeautifulSoup(response.text, 'html.parser')
items = soup.find_all('div', class_='item')
for index, item in enumerate(items):
rank = index + 1 + start
title = item.find('span', class_='title').get_text(strip=True)
bd = item.find('div', class_='bd')
if bd:
# 使用XPath提取年份、国家和类型信息
p_text = bd.find('p').text.strip()
details = p_text.split('\n')[1] # 获取第二行文本
year_country_genre = details.split('/')
year = year_country_genre[0].strip() if year_country_genre else "未知"
country = year_country_genre[1].strip() if len(year_country_genre) > 1 else "未知"
genre = year_country_genre[2].strip() if len(year_country_genre) > 2 else "未知"
else:
year = country = genre = "未知"
rating = item.find('span', class_='rating_num')
rating_text = rating.get_text(strip=True) if rating else "未知"
quote = item.find('p', class_='quote')
quote_text = quote.get_text(strip=True) if quote else "未知"
img_tag = item.find('img')
img_src = img_tag['src'] if img_tag and img_tag.has_attr('src') else ""
if img_src.startswith('//'):
img_src = 'https:' + img_src
# 下载图片并转换为二进制数据
img_data = requests.get(img_src).content
img = openpyxl_Image(BytesIO(img_data))
# 调整图片尺寸
img.width = 100 # 设置图片宽度
img.height = 150 # 设置图片高度
# 将图片添加到Excel中
ws.add_image(img, f'H{rank}')
# 将数据写入Excel
ws.append([rank, title, year, country, genre, rating_text, quote_text])
else:
print(f"请求第{page_num}页失败,状态码: {response.status_code}")
break
# 保存Excel文件
wb.save("douban_top250.xlsx")
运行爬虫
将上述代码保存为.py文件,并在命令行运行。确保你的网络环境可以访问豆瓣,且豆瓣网站结构没有发生变化。
结果示例

在Python爬虫教程中,requests库是用于发送HTTP请求的关键库。以下是对代码中requests库部分的详细解析:
设置请求头部
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36'
}
这里创建了一个名为headers的字典,包含了一个HTTP请求头部字段User-Agent,它告诉服务器,我们的请求是从一个常见的Web浏览器发出的。模拟浏览器的User-Agent字符串可以防止网站识别出请求是由脚本发出的,有些网站会据此阻止非浏览器的访问。在此案例中如果我们不设置请求头部会出现请求失败
![]()
发送GET请求
response = requests.get(url, headers=headers)
使用requests.get方法发送一个GET请求到指定的url。headers参数传递了我们之前设置的请求头部,这有助于模拟一个真实的浏览器请求。requests.get方法返回一个Response对象,其中包含了服务器响应的所有信息。
检查请求是否成功
if response.status_code == 200:
# 请求成功,继续处理
else:
print(f"请求失败,状态码: {response.status_code}")
这里检查了Response对象的status_code属性,它是服务器响应的状态码。状态码200表示请求成功,我们将继续执行程序。任何其他状态码都表示有错误发生,这里我们只是打印出了错误的状态码。
if response.status_code == 200:
soup = BeautifulSoup(response.text, 'html.parser')
items = soup.find_all('div', class_='item')
else:
print(f"请求第{page_num}页失败,状态码: {response.status_code}")
break
在Python爬虫教程中,BeautifulSoup和openpyxl库分别用于解析HTML内容和操作Excel文件。以下是对此案例代码中这两个库部分的解析:导入BeautifulSoup库
解析HTML内容
soup = BeautifulSoup(response.text, 'html.parser')
使用BeautifulSoup类创建了一个对象soup,它将response.text(即服务器响应的HTML内容)作为输入。第二个参数html.parser指定了解析器,告诉`BeautifulSoup使用Python标准库中的HTML解析器来解析文档。
### 查找bd标签
bd = soup.find('div', class_='bd')
`find`方法用于查找文档中的第一个匹配指定条件的元素。这里,它查找类名为`bd`的`<div>`标签。
提取年份、国家和类型信息
p_text = bd.find('p').text.strip()
details = p_text.split('\n')[1]
year_country_genre = details.split('/')
这里,首先使用`find`方法找到`bd`标签内的`<p>`标签,并获取其文本内容。然后使用`strip`方法去除文本两端的空白符,接着按换行符`\n`分割文本,取第二行(索引为1)作为年份、国家和类型的信息。最后,使用`split('/')`方法按斜杠`/`分割这些信息。
导入openpyxl库
from openpyxl import Workbook
这行代码导入了`openpyxl`库的`Workbook`类。`openpyxl`是一个用于读写Excel 2010 xlsx/xlsm/xltx文件的库。
创建Excel工作簿
wb = Workbook()
ws = wb.active
ws.title = "Douban Top 250"
这里创建了一个新的Excel工作簿对象`wb`,并获取了活动工作表`ws`。然后,为工作表设置了标题。
添加标题行
ws.append(["排名", "电影名", "年份", "国家", "类型", "评分", "一句话影评", "链接"])
使用append方法向工作表中添加一行,作为标题行。
ws.append([index, title, year, country, genre, rating, quote, link])
对于每个电影条目,将提取的数据作为列表传递给`append`方法,添加到工作表中。
保存Excel文件
wb.save("douban_top250.xlsx")
注意事项
- 遵守爬虫协议:在爬取网站数据前,请确保遵守网站的robots.txt文件规定,不要对网站服务器造成过大压力。
- 合法性:确保爬取数据的合法性,不要用于商业用途或其他非法用途。
- 反爬措施:豆瓣等网站可能会有反爬措施,如遇到访问限制,应适当降低爬取频率或使用代理IP

417



被折叠的 条评论
为什么被折叠?



