Python爬取豆瓣图书网Top250 实战
Python爬取豆瓣图书网Top250 实战
只是用于学习,请不要恶意攻击别人的网站,尊重他人。
1. 引言
豆瓣图书Top250是一个经典的图书排行榜,包含了大量优质图书的信息。本文将深入探讨如何使用Python爬取豆瓣图书Top250的内容,并将数据分别保存到数据库(SQLite)和文本文档中。我们将涵盖反爬虫策略、异常处理、数据清洗等技术细节,并提醒大家在爬取数据时尊重他人的劳动成果。
2. 技术栈与工具
在开始之前,请确保你已经安装了以下Python库:
requests
:用于发送HTTP请求。BeautifulSoup
:用于解析HTML内容。sqlite3
:用于操作SQLite数据库。fake_useragent
:用于生成随机的User-Agent
头,避免被反爬虫机制拦截。
你可以通过以下命令安装这些库:
pip install requests beautifulsoup4 fake_useragent
3. 爬取豆瓣图书Top250
3.1 反爬虫策略
为了避免被反爬虫机制拦截,我们需要采取以下措施:
- 随机
User-Agent
:使用fake_useragent
库生成随机的User-Agent
头。 - 请求延时:在每次请求之间添加适当的延时,避免频繁请求。
- 异常处理:捕获请求过程中可能出现的异常,确保程序稳定性。
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
import time
import random
# 目标URL
url = 'https://book.douban.com/top250'
# 生成随机User-Agent
ua = UserAgent()
headers = {
'User-Agent': ua.random
}
# 发送HTTP请求
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 检查请求是否成功
except requests.exceptions.RequestException as e:
print(f'请求失败: {e}')
exit()
# 添加随机延时(1-3秒)
time.sleep(random.uniform(1, 3))
3.2 解析HTML内容
使用BeautifulSoup
解析HTML内容,并提取每本书的书名、评分和评价人数。为了提高代码的健壮性,我们需要对可能缺失的数据进行处理。
# 解析HTML内容
soup = BeautifulSoup(response.text, 'html.parser')
# 找到所有图书信息
books = soup.find_all('tr', class_='item')
# 存储图书信息
book_list = []
for book in books:
try:
# 提取书名
title = book.find('div', class_='pl2').find('a')['title']
# 提取评分
rating = book.find('span', class_='rating_nums').text
# 提取评价人数
people = book.find('span', class_='pl').text.strip().strip('()')
# 数据清洗:确保评分和评价人数为有效值
if not title or not rating or not people:
continue
# 将图书信息添加到列表中
book_list.append({
'title': title,
'rating': float(rating),
'people': int(people.replace(',', '')) # 去除千分位逗号
})
except AttributeError as e:
print(f'解析错误: {e}')
continue
# 打印结果
for book in book_list:
print(f"书名: {book['title']}, 评分: {book['rating']}, 评价人数: {book['people']}")
4. 保存数据到文本文档
将爬取的数据保存到文本文档中,每行存储一本书的信息。为了便于后续分析,我们可以使用CSV格式保存数据。
import csv
# 保存数据到CSV文件
with open('douban_top250.csv', 'w', encoding='utf-8', newline='') as file:
writer = csv.writer(file)
writer.writerow(['书名', '评分', '评价人数']) # 写入表头
for book in book_list:
writer.writerow([book['title'], book['rating'], book['people']])
print("数据已保存到CSV文件: douban_top250.csv")
5. 保存数据到SQLite数据库
5.1 创建数据库和表
使用SQLite数据库存储数据,确保数据结构的规范性和可扩展性。
import sqlite3
# 连接到SQLite数据库(如果数据库不存在,则会自动创建)
conn = sqlite3.connect('douban_top250.db')
cursor = conn.cursor()
# 创建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
rating REAL NOT NULL,
people INTEGER NOT NULL
)
''')
# 提交更改
conn.commit()
5.2 插入数据
将爬取的数据插入到数据库中,并使用事务机制确保数据的一致性。
# 使用事务插入数据
try:
cursor.executemany('''
INSERT INTO books (title, rating, people)
VALUES (?, ?, ?)
''', [(book['title'], book['rating'], book['people']) for book in book_list])
conn.commit()
except sqlite3.Error as e:
print(f'数据库插入错误: {e}')
conn.rollback()
finally:
# 关闭数据库连接
conn.close()
print("数据已保存到数据库: douban_top250.db")
6. 完整代码
以下是完整的代码:
import requests
from bs4 import BeautifulSoup
from fake_useragent import UserAgent
import time
import random
import csv
import sqlite3
# 目标URL
url = 'https://book.douban.com/top250'
# 生成随机User-Agent
ua = UserAgent()
headers = {
'User-Agent': ua.random
}
# 发送HTTP请求
try:
response = requests.get(url, headers=headers, timeout=10)
response.raise_for_status() # 检查请求是否成功
except requests.exceptions.RequestException as e:
print(f'请求失败: {e}')
exit()
# 添加随机延时(1-3秒)
time.sleep(random.uniform(1, 3))
# 解析HTML内容
soup = BeautifulSoup(response.text, 'html.parser')
# 找到所有图书信息
books = soup.find_all('tr', class_='item')
# 存储图书信息
book_list = []
for book in books:
try:
# 提取书名
title = book.find('div', class_='pl2').find('a')['title']
# 提取评分
rating = book.find('span', class_='rating_nums').text
# 提取评价人数
people = book.find('span', class_='pl').text.strip().strip('()')
# 数据清洗:确保评分和评价人数为有效值
if not title or not rating or not people:
continue
# 将图书信息添加到列表中
book_list.append({
'title': title,
'rating': float(rating),
'people': int(people.replace(',', '')) # 去除千分位逗号
})
except AttributeError as e:
print(f'解析错误: {e}')
continue
# 保存数据到CSV文件
with open('douban_top250.csv', 'w', encoding='utf-8', newline='') as file:
writer = csv.writer(file)
writer.writerow(['书名', '评分', '评价人数']) # 写入表头
for book in book_list:
writer.writerow([book['title'], book['rating'], book['people']])
print("数据已保存到CSV文件: douban_top250.csv")
# 连接到SQLite数据库
conn = sqlite3.connect('douban_top250.db')
cursor = conn.cursor()
# 创建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS books (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
rating REAL NOT NULL,
people INTEGER NOT NULL
)
''')
# 使用事务插入数据
try:
cursor.executemany('''
INSERT INTO books (title, rating, people)
VALUES (?, ?, ?)
''', [(book['title'], book['rating'], book['people']) for book in book_list])
conn.commit()
except sqlite3.Error as e:
print(f'数据库插入错误: {e}')
conn.rollback()
finally:
# 关闭数据库连接
conn.close()
print("数据已保存到数据库: douban_top250.db")
7. 尊重他人劳动成果
在爬取数据时,请务必尊重他人的劳动成果。以下是一些需要注意的事项:
- 遵守网站的
robots.txt
文件:robots.txt
文件规定了哪些页面可以被爬取,哪些页面不可以。请确保你的爬虫遵守这些规则。 - 控制请求频率:频繁的请求可能会对服务器造成负担,甚至导致你的IP被封禁。建议在爬取时添加适当的延时。
- 合理使用数据:爬取的数据应仅用于个人学习或研究,不得用于商业用途或侵犯他人权益。
8. 总结
本文深入探讨了如何使用Python爬取豆瓣图书Top250的内容,并详细介绍了反爬虫策略、异常处理、数据清洗等技术细节。通过本文的学习,你可以掌握高效的网页爬取技术以及数据存储方法。同时,我们也强调了在爬取数据时尊重他人劳动成果的重要性。希望这篇教程对你有所帮助!