python如何爬取豆瓣各分类书单

发布时间:2022-01-12 09:49:36 作者:iii
来源:亿速云 阅读:349
# Python如何爬取豆瓣各分类书单

## 前言

在当今信息爆炸的时代,获取特定领域的书籍信息对于读者、研究者和数据分析师来说都至关重要。豆瓣作为中国最具影响力的图书、电影和音乐分享平台,拥有丰富的图书数据和用户评价。本文将详细介绍如何使用Python爬取豆瓣各分类书单,帮助读者快速获取所需图书信息。

## 一、准备工作

### 1.1 环境配置

在开始爬取之前,需要确保已安装以下Python库:

```python
pip install requests beautifulsoup4 pandas

1.2 分析目标网站

首先访问豆瓣读书分类页面:https://book.douban.com/tag/。观察页面结构:

  1. 左侧为分类导航栏
  2. 右侧为具体分类下的图书列表
  3. 每个图书条目包含:书名、作者、评分、评价人数等信息

二、爬取分类列表

2.1 获取所有分类

import requests
from bs4 import BeautifulSoup

def get_all_tags():
    url = "https://book.douban.com/tag/"
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    tags = []
    # 获取左侧分类导航栏
    tag_table = soup.find('div', class_='article')
    for td in tag_table.find_all('td'):
        tag = td.a.text.strip()
        tags.append(tag)
    
    return tags

all_tags = get_all_tags()
print(f"共获取到{len(all_tags)}个分类")

2.2 处理分类URL

每个分类对应一个特定的URL,格式为:https://book.douban.com/tag/分类名称

三、爬取单分类书单

3.1 获取单页图书信息

def get_books_by_tag(tag, page=1):
    url = f"https://book.douban.com/tag/{tag}?start={(page-1)*20}&type=T"
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
    response = requests.get(url, headers=headers)
    soup = BeautifulSoup(response.text, 'html.parser')
    
    books = []
    items = soup.find_all('li', class_='subject-item')
    for item in items:
        try:
            title = item.find('h2').a['title']
            pub_info = item.find('div', class_='pub').text.strip().split('/')
            author = pub_info[0].strip()
            publisher = pub_info[-3].strip() if len(pub_info) > 3 else ''
            pub_date = pub_info[-2].strip() if len(pub_info) > 2 else ''
            price = pub_info[-1].strip() if len(pub_info) > 1 else ''
            
            rating = item.find('span', class_='rating_nums').text if item.find('span', class_='rating_nums') else '0.0'
            rating_num = item.find('span', class_='pl').text.strip()[1:-1] if item.find('span', class_='pl') else '0'
            
            books.append({
                'title': title,
                'author': author,
                'publisher': publisher,
                'pub_date': pub_date,
                'price': price,
                'rating': float(rating),
                'rating_num': int(rating_num.replace(',', '')),
                'tag': tag
            })
        except Exception as e:
            print(f"解析错误: {e}")
            continue
    
    return books

3.2 处理分页

豆瓣每个分类页面默认显示20条记录,通过修改URL中的start参数可以获取更多数据。

def get_all_books_by_tag(tag, max_pages=5):
    all_books = []
    for page in range(1, max_pages+1):
        print(f"正在爬取{tag}分类第{page}页...")
        books = get_books_by_tag(tag, page)
        if not books:
            break
        all_books.extend(books)
        # 避免请求过于频繁
        time.sleep(2)
    return all_books

四、数据存储与处理

4.1 存储为CSV文件

import pandas as pd

def save_to_csv(books, filename='douban_books.csv'):
    df = pd.DataFrame(books)
    df.to_csv(filename, index=False, encoding='utf_8_sig')
    print(f"数据已保存到{filename}")

4.2 存储到数据库

如果需要存储到MySQL数据库:

import pymysql

def save_to_mysql(books):
    conn = pymysql.connect(
        host='localhost',
        user='root',
        password='password',
        database='douban',
        charset='utf8mb4'
    )
    
    cursor = conn.cursor()
    sql = """INSERT INTO books 
             (title, author, publisher, pub_date, price, rating, rating_num, tag) 
             VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"""
    
    for book in books:
        cursor.execute(sql, (
            book['title'], book['author'], book['publisher'],
            book['pub_date'], book['price'], book['rating'],
            book['rating_num'], book['tag']
        ))
    
    conn.commit()
    conn.close()

五、反爬虫策略应对

豆瓣有一定的反爬虫机制,需要注意以下几点:

  1. 设置请求头:特别是User-Agent
  2. 控制请求频率:添加time.sleep()避免频繁请求
  3. 使用代理IP:如果IP被封,可以考虑使用代理
  4. 使用Session:保持会话
session = requests.Session()
session.headers.update({
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    'Accept-Language': 'zh-CN,zh;q=0.9'
})

六、完整代码示例

import requests
from bs4 import BeautifulSoup
import pandas as pd
import time
import random

def main():
    # 1. 获取所有分类
    tags = ['小说', '文学', '历史']  # 示例分类,实际可替换为get_all_tags()
    
    all_books = []
    for tag in tags:
        print(f"开始爬取{tag}分类...")
        books = get_all_books_by_tag(tag, max_pages=3)
        all_books.extend(books)
        print(f"{tag}分类爬取完成,共获取{len(books)}本书")
        time.sleep(random.randint(3, 6))
    
    # 保存数据
    save_to_csv(all_books)
    print("所有分类爬取完成!")

if __name__ == '__main__':
    main()

七、数据分析示例

获取数据后可以进行简单的分析:

df = pd.read_csv('douban_books.csv')

# 按分类统计
tag_stats = df.groupby('tag').agg({
    'title': 'count',
    'rating': 'mean',
    'rating_num': 'sum'
}).sort_values('title', ascending=False)

# 评分最高的书籍
top_rated = df.sort_values('rating', ascending=False).head(10)

八、注意事项

  1. 遵守豆瓣的robots.txt协议,不要过度爬取
  2. 仅用于学习和研究目的,不要用于商业用途
  3. 爬取的数据量较大时,建议分批次进行
  4. 豆瓣可能会更新页面结构,需要定期维护爬虫代码

结语

本文详细介绍了如何使用Python爬取豆瓣各分类书单的全过程。通过这种方法,你可以获取丰富的图书数据用于各种分析目的。在实际应用中,可以根据需求调整爬取策略和数据存储方式。希望本文能帮助你高效地获取豆瓣图书数据!

注意:本文代码示例仅供参考,实际使用时请遵守相关法律法规和网站的使用条款。 “`

推荐阅读:
  1. Python爬取豆瓣高分电影前250名
  2. Python利用Scrapy框架爬取豆瓣电影示例

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:如何进行Android Hook技术的实践

下一篇:MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决方法是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》