只是用于学习,请不要恶意攻击别人的网站,尊重他人。
豆瓣图书Top250是一个经典的图书排行榜,包含了大量优质图书的信息。本文将深入探讨如何使用Python爬取豆瓣图书Top250的内容,并将数据分别保存到数据库(SQLite)和文本文档中。我们将涵盖反爬虫策略、异常处理、数据清洗等技术细节,并提醒大家在爬取数据时尊重他人的劳动成果。
在开始之前,请确保你已经安装了以下Python库:
requests
:用于发送HTTP请求。BeautifulSoup
:用于解析HTML内容。sqlite3
:用于操作SQLite数据库。fake_useragent
:用于生成随机的User-Agent
头,避免被反爬虫机制拦截。你可以通过以下命令安装这些库:
pip install requests beautifulsoup4 fake_useragent
为了避免被反爬虫机制拦截,我们需要采取以下措施:
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))
使用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']}")
将爬取的数据保存到文本文档中,每行存储一本书的信息。为了便于后续分析,我们可以使用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")
使用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()
将爬取的数据插入到数据库中,并使用事务机制确保数据的一致性。
# 使用事务插入数据
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")
以下是完整的代码:
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")
在爬取数据时,请务必尊重他人的劳动成果。以下是一些需要注意的事项:
robots.txt
文件:robots.txt
文件规定了哪些页面可以被爬取,哪些页面不可以。请确保你的爬虫遵守这些规则。本文深入探讨了如何使用Python爬取豆瓣图书Top250的内容,并详细介绍了反爬虫策略、异常处理、数据清洗等技术细节。通过本文的学习,你可以掌握高效的网页爬取技术以及数据存储方法。同时,我们也强调了在爬取数据时尊重他人劳动成果的重要性。希望这篇教程对你有所帮助!