当前位置: 首页 > article >正文

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 反爬虫策略

为了避免被反爬虫机制拦截,我们需要采取以下措施:

  1. 随机User-Agent:使用fake_useragent库生成随机的User-Agent头。
  2. 请求延时:在每次请求之间添加适当的延时,避免频繁请求。
  3. 异常处理:捕获请求过程中可能出现的异常,确保程序稳定性。
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. 尊重他人劳动成果

在爬取数据时,请务必尊重他人的劳动成果。以下是一些需要注意的事项:

  1. 遵守网站的robots.txt文件robots.txt文件规定了哪些页面可以被爬取,哪些页面不可以。请确保你的爬虫遵守这些规则。
  2. 控制请求频率:频繁的请求可能会对服务器造成负担,甚至导致你的IP被封禁。建议在爬取时添加适当的延时。
  3. 合理使用数据:爬取的数据应仅用于个人学习或研究,不得用于商业用途或侵犯他人权益。

8. 总结

本文深入探讨了如何使用Python爬取豆瓣图书Top250的内容,并详细介绍了反爬虫策略、异常处理、数据清洗等技术细节。通过本文的学习,你可以掌握高效的网页爬取技术以及数据存储方法。同时,我们也强调了在爬取数据时尊重他人劳动成果的重要性。希望这篇教程对你有所帮助!


http://www.kler.cn/a/505163.html

相关文章:

  • Python 实现 NLP 的完整流程
  • STM32-keil安装时遇到的一些问题以及解决方案
  • 【STM32】HAL库USB实现软件升级DFU的功能操作及配置
  • Elasticsearch技术标准解析与实践案例
  • 如何在 Linux、MacOS 以及 Windows 中打开控制面板
  • 数仓建模(五)选择数仓技术栈:Hive ClickHouse 其它
  • 【工具类】获取日出日落时间的Java工具类
  • 全网唯一的工具 苹果手机备忘录全自动导出备份
  • QT与基恩士PLC采用上位链路通信实现
  • Jmeter配置服务代理器 Proxy(二)
  • 云计算技术深度解析与代码实践
  • 机器学习实战33-LSTM+随机森林模型在股票价格走势预测与买卖点分类中的应用
  • Python AI教程之二十一:监督学习之支持向量机(SVM)算法
  • 「实战应用」如何为DHTMLX JavaScript 甘特图添加进度线
  • 深入剖析 Wireshark:网络协议分析的得力工具
  • 在 Go语言中一个字段可以包含多种类型的值的设计与接种解决方案
  • 如何修复Android上未安装的应用程序
  • 【声音场景分类--论文阅读】
  • 【Rust练习】28.use and pub
  • 【Qt】02-信号与槽函数
  • 全域数据资产管理平台 | SimbaFabric
  • git merge 压缩提交
  • 大模型微调|使用LoRA微调Qwen2.5-7B-Instruct完成文本分类任务
  • Unity|Tetris|俄罗斯方块复刻1(C#)
  • RK3588-NPU pytorch-image-models 模型编译测试
  • cursor重构谷粒商城01——为何要重构谷粒商城