Scrapy 的运行流程

Scrapy 的运行流程由以下几个步骤组成,每个步骤对应一个组件,分别负责请求的拦截、响应的解析、数据项的处理等任务:

  1. 中间件(Middleware):拦截和修改请求、响应的中间层。
  2. Spider:定义爬虫的主要逻辑,负责解析响应内容、生成数据项和新请求。
  3. 管道(Pipeline):对由 Spider 生成的数据项进行清洗和存储。

以下是对这些组件及其配置的说明,帮助快速理解 Scrapy 的架构及组件配置方法。


1. 中间件(Middleware)

中间件用于对请求和响应进行预处理和后处理。在 Scrapy 中,可以通过配置多个中间件,并按照优先级顺序执行。这使得我们可以通过中间件实现诸如设置代理、重试机制等功能。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
# middlewares.py

class ProxyMiddleware:
def process_request(self, request, spider):
# 设置代理
request.meta['proxy'] = 'http://yourproxy.com' # 演示用途,替换为实际代理

class RetryMiddleware:
def process_response(self, request, response, spider):
# 非200响应则重试
if response.status != 200:
return request # 演示用途,重试请求
return response

中间件配置:

在 Scrapy 的 settings.py 文件中,可以通过 DOWNLOADER_MIDDLEWARES 来配置中间件,并指定其优先级(数值越小,优先级越高)。

1
2
3
4
5
6
7

# settings.py

DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.ProxyMiddleware': 100,
'myproject.middlewares.RetryMiddleware': 200,
}

注意:以上中间件代码和配置仅为演示,实际使用时需根据具体需求调整代理 URL 和重试逻辑。请注意优先级的配置值,确保中间件的执行顺序符合预期。


2. Spider

Spider 是 Scrapy 的核心组件之一,用于定义爬虫逻辑。每个 Spider 都包含 parse 等方法,用于解析页面数据、生成新的请求和数据项。

每个 Spider 的主要职责包括:

  1. 数据提取:从响应中提取数据。
  2. 生成新请求:在需要抓取其他页面时生成新请求。
  3. 生成数据项:将解析完成的数据封装为数据项,供管道处理。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# spiders/example_spider.py

import scrapy

class ExampleSpider(scrapy.Spider):
name = 'example'

def start_requests(self):
# 起始请求,URL请替换为实际要抓取的页面
yield scrapy.Request(url='http://example.com', callback=self.parse)

def parse(self, response):
# 从页面中提取数据
for item in response.xpath('//div[@class="item"]'):
yield {
'title': item.xpath('.//h2/text()').get(), # 提取标题
'link': item.xpath('.//a/@href').get() # 提取链接
}

# 生成新请求
next_page = response.xpath('//a[@rel="next"]/@href').get()
if next_page:
yield scrapy.Request(url=next_page, callback=self.parse)

Spider 配置:

可以在 settings.py 中通过 CONCURRENT_REQUESTSDOWNLOAD_DELAY 等配置项控制 Spider 的抓取速度和请求频率,以防止被目标网站封禁。

1
2
3
4
5
6
# settings.py

# 同时并发请求数
CONCURRENT_REQUESTS = 16
# 请求间隔(秒)
DOWNLOAD_DELAY = 1

注意:以上 Spider 和配置代码用于演示,具体配置需根据实际抓取任务调整,确保不会对目标站点造成负担。


3. 管道(Pipeline)

管道用于对 Spider 生成的数据项进行进一步处理,如数据清洗和存储。每个数据项会按顺序经过所有已定义的管道。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
# pipelines.py

class DatabasePipeline:
def process_item(self, item, spider):
# 存储数据项到数据库
save_to_database(item) # 演示用途,需实现具体存储逻辑
return item

class DownloadPipeline:
def process_item(self, item, spider):
# 下载文件
download_file(item['link']) # 演示用途,需实现具体下载逻辑
return item

管道配置:

settings.py 中可以通过 ITEM_PIPELINES 配置管道的优先级(数值越小,优先级越高)。

1
2
3
4
5
6
# settings.py

ITEM_PIPELINES = {
'myproject.pipelines.DatabasePipeline': 100,
'myproject.pipelines.DownloadPipeline': 200,
}

注意:以上代码仅作结构示例,save_to_databasedownload_file 是假设的函数,需根据具体存储和下载需求实现。


4. Scrapy 的整体运行流程

在 Scrapy 的抓取流程中,各个组件通过以下步骤配合完成整个数据抓取任务:

  1. 请求处理 - 请求在发出前经过各个中间件处理,添加必要的信息。
  2. Spider 解析 - Spider 处理请求返回的响应,通过 parse 等方法解析内容,生成数据项和新请求。
  3. 数据处理 - 解析生成的数据项被传递到管道,由管道完成清洗和存储。
  4. 任务完成 - Scrapy 引擎不断重复上述步骤,直到所有请求和数据项被处理完毕。

通过这种方式,Scrapy 实现了数据抓取的完整闭环,开发者可以通过配置不同的中间件、Spider 和管道,自定义每个流程环节的具体逻辑,满足各种数据抓取需求。

一个简单的Scrapy项目的流程图:

一个简单的Scrapy项目的流程图


额外组件扩充

Scrapy 提供了一些额外的关键组件,帮助开发者更灵活、高效地构建爬虫。以下是对这些扩展组件及其配置的介绍。

1. 调度器(Scheduler)

调度器管理请求队列,确保所有请求被合理调度。其内部维护一个优先级队列,以保证高优先级的请求优先被处理。

配置示例

settings.py 中设置调度器的请求队列持久化配置:

1
2
3
4
5
# settings.py

# 使用磁盘队列进行持久化,防止中断后请求丢失
SCHEDULER = "scrapy.core.scheduler.Scheduler"
SCHEDULER_PERSIST = True

2. 下载器(Downloader)

下载器是 Scrapy 的核心组件之一,负责发送请求和接收响应。下载器结合中间件实现异步请求,从而提升爬取速度。

配置示例

可以在 settings.py 中配置下载器的请求超时等参数:

1
2
3
4
# settings.py

# 下载超时设置
DOWNLOAD_TIMEOUT = 15

3. 信号(Signals)

信号系统允许开发者在特定事件(如 Spider 开始和结束)触发时执行自定义代码,为爬虫添加钩子函数。

示例代码

以下代码展示了如何使用信号系统在 Spider 开始时执行自定义逻辑。

1
2
3
4
5
6
7
8
9
10
11
from scrapy import signals

class CustomExtension:
@classmethod
def from_crawler(cls, crawler):
ext = cls()
crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)
return ext

def spider_opened(self, spider):
print(f"Spider {spider.name} started")

配置示例

settings.py 中启用扩展,配置优先级以控制扩展的执行顺序:

1
2
3
4
5
# settings.py

EXTENSIONS = {
'myproject.extensions.CustomExtension': 500,
}

4. 扩展(Extensions)

扩展功能允许在 Scrapy 中添加自定义模块,用于监控 Spider 运行状态或实现特殊逻辑。

配置示例

可以在 settings.py 中启用和配置扩展的优先级:

1
2
3
4
5
# settings.py

EXTENSIONS = {
'myproject.extensions.YourCustomExtension': 100,
}

通过配置以上组件,Scrapy 提供了强大的扩展性和灵活性。开发者可以根据爬虫任务需求,对每个组件及其配置进行精细控制,从而实现高效、可扩展的爬虫项目。