爬虫案例之小说爬取

1.引言

1.1主题

本博客旨在通过一个具体的案例——使用scrapy框架采集小说内容,并存储子txt文件中,来展示网络爬虫技术的实际应用。我们将探索如何使用爬虫技术来自动收集、处理和分析网络上的公开数据,以及如何将这些数据转化为有价值的信息。

2.数据来源

url:https://www.bxuu.net/31/31909/

3.介绍scrapy框架

Scrapy是一个快速的、高层次的web抓取和网页爬虫框架,用于抓取web站点并从页面中提取结构化的数据。它提供了一套非常灵活的机制来抓取网站,并且可以用于各种用途,如数据挖掘、信息处理或历史存档。
以下是Scrapy框架的一些主要特点:

  1. 异步处理:Scrapy是基于Twisted异步网络框架构建的,这意味着它可以在不阻塞的情况下进行快速的网页请求。
  2. 高性能:Scrapy设计用于处理大量的并发请求,因此它非常适合大规模的抓取任务。
  3. 可扩展性:Scrapy允许用户通过编写扩展来增加额外的功能,这些扩展可以在抓取过程中的特定阶段被调用。
  4. 中间件支持:Scrapy提供了请求/响应中间件,用户可以自定义中间件来处理请求和响应。
  5. 选择器:Scrapy提供了XPath和CSS选择器,使得从HTML/XML响应中提取数据变得简单。
  6. 内置支持:Scrapy内置了对多种数据格式的支持,如JSON、CSV和XML。
  7. 命令行工具:Scrapy提供了一个命令行工具,可以通过命令行来运行爬虫、查看日志和执行其他任务。
  8. 项目结构:Scrapy项目通常包含一个项目文件、一个或多个爬虫文件、一个设置文件、一个中间件文件和一个管道文件。
  9. 管道(Pipelines):Scrapy允许定义管道来处理抓取到的数据,例如清洗、验证和存储。
  10. 去重:Scrapy内置了去重机制,可以避免重复抓取相同的页面。
  11. 支持代理:Scrapy支持使用代理服务器进行抓取,这对于绕过IP限制非常有用。
  12. 用户代理和Cookies:Scrapy可以模拟浏览器行为,包括设置用户代理和处理Cookies。

4.具体操作

4.1 命令行下载必要的库

pip install Scrapy # 注:windows平台需要依赖pywin32
pip install pypiwin32

4.2 创建项目

scrapy startproject myspider
cd myspider
scrapy genspider bxuu bxuu.net

4.3 全局设置-settings.py

# Scrapy 配置文件 for myspider2 项目
#
# 为了简化,此文件仅包含被认为是重要或
# 常见的设置。您可以通过以下链接找到更多设置:
#
#     https://docs.scrapy.org/en/latest/topics/settings.html
#     https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
#     https://docs.scrapy.org/en/latest/topics/spider-middleware.html

# 用于生成随机的 User-Agent
from fake_useragent import UserAgent  

# 定义机器人名称
BOT_NAME = "myspider2"

# 定义蜘蛛模块所在的位置
SPIDER_MODULES = ["myspider2.spiders"]
NEWSPIDER_MODULE = "myspider2.spiders"

# 通过识别自己(和您的网站)在 user-agent 上负责任地爬取
USER_AGENT = UserAgent().random  # 使用随机 User-Agent

# 遵守 robots.txt 规则
ROBOTSTXT_OBEY = False  # 默认情况下不遵守

# 配置项目管道
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   "myspider2.pipelines.BxuuPipeline": 300,
}


4.4 采集数据

import scrapy

class BxuuSpider(scrapy.Spider):
    # 爬虫名称
    name = "bxuu"
    # 允许的域名
    allowed_domains = ["bxuu.net"]
    # 起始URL
    start_urls = ["https://www.bxuu.net/31/31909/"]

    def parse(self, response):
        # 设置基础URL
        self.base_url = 'https://www.bxuu.net/31/31909/'
        # 获取书名并截取前7个字符
        book_name = response.xpath('//*[@id="ztopinfo"]/div[2]/h1/text()').extract_first()
        book_name = book_name[:7]
        print(book_name)
        # 获取章节标题和URL
        chapters = response.xpath("//*[@id='zcontent']/dl/dd/a/text()").getall()[:135]
        urls = response.xpath("//*[@id='zcontent']/dl/dd/a/@href").getall()[:135]
        # 遍历章节和URL
        for index,(url,chapter) in enumerate(zip(urls,chapters),start=1):
            # 构建完整URL
            compete_url=self.base_url+url.split('/')[-1]
            print(f'chapter:{chapter},url:{compete_url}')
            # 发送请求到章节页面
            yield scrapy.Request(compete_url,callback=self.parse_chapter,meta={'book_name': book_name, 'chapter': chapter,'index':index})

    def parse_chapter(self,response):
        # 获取章节内容
        content =response.xpath("//*[@id='content']/text()").extract()
        content = ' '.join(content)
        index = response.meta['index']
        chapter = response.meta['chapter']
        # 组装并返回章节信息
        yield {
            'book_name': response.meta['book_name'],
            'chapter':chapter,
            'content': content,
            'index': index
        }


4.5 保存数据-pipelines.py

# 在这里定义您的项目管道(pipeline)
#
# 别忘了在设置项`ITEM_PIPELINES`中添加您的管道
# 请参考: https://docs.scrapy.org/en/latest/topics/item-pipeline.html

# 对于使用统一接口处理不同类型的项目(item)很有用
from itemadapter import ItemAdapter
import os

# 定义BxuuPipeline类,用于处理爬取到的项目数据
class BxuuPipeline:
    # 当Spider开启时调用,用于做一些初始化工作
    def open_spider(self, spider):
        # 打印开始爬取信息
        print("开始爬取")

    # 用于处理每个采集到的项目(item)
    def process_item(self, item, spider):
        # 获取书籍的名称,用于创建目录
        dir_path = item.get('book_name')
        # 如果书籍目录不存在,则创建
        if not os.path.exists(dir_path):
            os.mkdir(dir_path)
        # 获取章节的索引,用于文件命名
        index = str(item.get('index'))
        # 获取章节的标题
        chapter = item.get('chapter')
        # 构造文件名
        file_name = f"{index}_{chapter}.txt"
        # 构造文件的完整路径
        file_path = os.path.join(dir_path,file_name)
        # 如果文件不存在,则创建并写入章节内容
        if not os.path.exists(file_path):
            with open(file_path,'w',encoding='utf-8') as f:
                f.write(item.get('content'))
        # 返回项目对象,以便后续管道继续处理
        return item

    # 当Spider关闭时调用,用于做一些收尾工作
    def close_spider(self, spider):
        # 打印爬取结束信息
        print("爬取结束")

4.6 运行结果

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值