Scrapy是什么?

Scrapy是一个强大的Python爬虫框架,专门用于从网站上爬取结构化数据。你可以把它想象成一个”网络收割机”,自动浏览网页、采集信息并整理成你需要的格式。

为什么选择Scrapy?

  • 高效快捷:内置异步处理机制,比普通爬虫快很多
  • 功能全面:自动处理请求、响应、下载、数据提取全套流程
  • 扩展性强:通过中间件可以灵活扩展功能
  • 成熟稳定:经过多年发展,有强大的社区支持

💡 大白话解释:Scrapy就像是爬虫界的”自动化工厂”,你只需要告诉它要什么产品(数据)、去哪里拿(网址),它就能自动完成整个生产过程!

Scrapy架构图解

理解Scrapy的工作原理非常重要,下面是它的核心组件和工作流程:

引擎(Engine) – 整个框架的”大脑”,控制数据流
调度器(Scheduler) – 管理请求队列,决定下一个请求
下载器(Downloader) – 实际发送请求和接收响应
爬虫(Spiders) – 你编写的代码,定义如何爬取和数据提取
项目管道(Item Pipeline) – 数据处理和存储
中间件(Middlewares) – 扩展功能的钩子

工作流程:引擎获取初始请求 → 调度器排队 → 下载器获取网页 → 爬虫解析 → 提取的数据到管道 → 存储结果

安装Scrapy

Scrapy的安装非常简单,只需要一条命令:

pip install scrapy

安装完成后,可以通过以下命令验证是否安装成功:

scrapy version

常见安装问题

  • Windows用户:可能需要安装Microsoft Visual C++ Build Tools
  • Mac/Linux用户:通常直接安装即可
  • 如果遇到权限问题,可以添加–user参数

创建Scrapy项目

使用Scrapy命令行工具创建项目骨架:

scrapy startproject myproject

这个命令会创建一个名为myproject的文件夹,包含以下结构:

myproject/
├── scrapy.cfg # 项目配置文件
└── myproject/ # 项目Python模块
├── __init__.py
├── items.py # 定义数据模型
├── middlewares.py # 中间件定义
├── pipelines.py # 数据处理管道
├── settings.py # 项目设置
└── spiders/ # 爬虫目录
└── __init__.py

💡 理解项目结构:这个结构就像是你的”爬虫工厂”的车间布局,每个文件负责不同的功能,协同工作完成爬取任务。

编写你的第一个爬虫

在spiders目录中创建Python文件,定义一个Spider类:

import scrapy

class MySpider(scrapy.Spider):
    # 爬虫的唯一标识名
    name = ‘myspider’

    # 起始URL列表
    start_urls = [
        ‘http://example.com/page1’,
        ‘http://example.com/page2’
    ]

    # 处理响应的方法
    def parse(self, response):
        # 提取数据并返回Items或Requests
        title = response.css(‘h1::text’).get()
        yield {
            ‘title’: title,
            ‘url’: response.url
        }

核心组件详解

  • name:爬虫的唯一标识,必须唯一
  • start_urls:爬虫开始抓取的网址列表
  • parse():默认的回调方法,处理响应并提取数据
  • response:包含下载的网页内容,可以用CSS或XPath选择器提取数据

数据提取技巧

Scrapy提供了两种强大的选择器:CSS和XPath

CSS选择器示例

# 提取标题文本
response.css(‘title::text’).get()

# 提取所有链接的href属性
response.css(‘a::attr(href)’).getall()

# 提取文章内容
response.css(‘div.article-content p::text’).getall()

XPath选择器示例

# 提取标题文本
response.xpath(‘//title/text()’).get()

# 提取具有class=”price”的span元素
response.xpath(‘//span[@class=”price”]/text()’).get()

# 提取相对路径示例
divs = response.xpath(‘//div’)
for d in divs:
    d.xpath(‘.//p’) # 注意开头的点号

💡 选择器使用技巧:CSS选择器更简洁易读,适合简单场景;XPath更强大灵活,适合复杂文档结构。实际开发中可以根据需要使用混合方式。

数据处理管道(Item Pipeline)

管道负责处理爬虫提取的数据,常见用途:

  • 清洗数据(如去除空白、格式化)
  • 验证数据(检查字段是否完整)
  • 去重(避免重复数据)
  • 存储数据(保存到文件、数据库)

创建管道示例

1. 在items.py中定义Item

import scrapy

class ProductItem(scrapy.Item):
    name = scrapy.Field()
    price = scrapy.Field()
    url = scrapy.Field()

2. 在pipelines.py中创建管道

class JsonWriterPipeline:
    def open_spider(self, spider):
        self.file = open(‘products.json’, ‘w’)

    def close_spider(self, spider):
        self.file.close()

    def process_item(self, item, spider):
        line = json.dumps(dict(item)) + “\n”
        self.file.write(line)
        return item

3. 在settings.py中启用管道

ITEM_PIPELINES = {
    ‘myproject.pipelines.JsonWriterPipeline’: 300,
}

中间件(Middleware)

中间件是Scrapy的”插件系统”,允许你全局修改请求和响应

下载器中间件示例

添加自定义User-Agent:

class CustomUserAgentMiddleware:
    def process_request(self, request, spider):
        request.headers[‘User-Agent’] = ‘MyCustomAgent/1.0’
        return None

Spider中间件示例

处理爬虫输出的Items:

class ItemCountMiddleware:
    def __init__(self):
        self.item_count = 0

    def process_spider_output(self, response, result, spider):
        for item in result:
            if isinstance(item, scrapy.Item):
                self.item_count += 1
                spider.logger.info(f”已抓取 {self.item_count} 个商品”)
            yield item

💡 中间件使用场景:更换IP代理、自动重试失败请求、添加自定义HTTP头、处理异常、统计爬取指标等高级功能。