
Scrapy框架【扩展】
更新: 2025/2/24 字数: 0 字 时长: 0 分钟
另外还有几个实用方法:
open_spider(self, spider)
其中spider
即被开启的 Spider 对象,当 Spider 开启的时候会自动调用该方法,这里我们可以做一些初始化操作,如开启数据库连接等。close_spider(spider)
其中spider
即被关闭的 Spider 对象,当Spider关闭的时候会自动调用该方法,这里我们可以做一些收尾操作,如关闭数据库连接等。from_scrawler(cls, crawler)
是一个类方法,用@classmethod
标识,其中cls
就是 Class,crawler
就是 Crawler 对象,通过它我们可以拿到 Scrapy 的所有核心组件,如全局配置的每个信息。方法最后返回一个 Class 实例。
警告
每提取一条数据都会调用一次 process_item()
方法,而 open_spider()
方法和 close_spider()
方法在只会在整个爬虫流程中启动、关闭爬虫时,对项目管道操作调用一次。
前面我们已经了解了 Scrapy 的常用的基本组件,如 Spider
、Downloder Middleware
、Spider Middleware
、Item Pipeline
等,其实另外还有一个比较实用的组件 Extension
,中文翻译叫作“扩展”。利用它,我们可以完成我们想自定义的功能。
扩展介绍
Scrapy 提供了一个 Extension 机制,可以让我们添加和扩展一些自定义的功能。利用 Extension 我们可以注册一些处理方法并监听 Scrapy 运行过程中的各个信号,做到在发生某个事件时执行我们自定义的方法。
内置扩展
Scrapy 已经内置了一些 Extension,如 LogStats
用于记录一些基本的爬取信息,比如爬取的页面数量、提取的 Item 数量等,Corestates
用于统计爬取过程中的核心统计信息,如开始爬取时间、爬取结束时间等。
定制扩展
我们也可以实现自定义的 Extension,主要分为两步:
- 实现一个 Python 类,然后实现对应的处理方法,如实现一个
spider_opened
方法用于处理 Spider 开始爬取时执行的操作,可以接收一个spider
参数并对其进行操作。 - 定义
from_crawler
类方法,其第一个参数是cls
类对象,第二个参数是crawler
。利用crawler
的signals
对象将Scrapy
的各个信号和已经定义的处理方法关联起来。
实现方法
我们在项目文件夹下新建一个 extensions.py
文件,添加如下代码:这里我们定义了一个 NotificationExtension
类,实现了 spider_opened
、spider_closed
、spider_scraped
方法,分别对应爬取开始、爬取结束、爬取到 Item 的处理。接着调用了 requests
向目标地址发送对应的事件,其中包含两个字段:一个是 event
,代表事件的名称;另一个是 data
,代表一些附加数据,如 Spider 的名称、Item 的具体内容。
import requests
# 接收消息地址
NOTIFICATION_URL = 'http://localhost:5000/notify'
class NotificationExtension(object):
# 爬取开始
def spider_opened(self, spider):
requests.post(NOTIFICATION_URL, json={
'event': 'SPIDER_OPENED',
'data': {'spider_name': spider.name}
})
# 爬取结束
def spider_closed(self, spider):
requests.post(NOTIFICATION_URL, json={
'event': 'SPIDER_CLOSED',
'data': {'spider_name': spider.name}
})
# 爬取Item
def spider_scraped(self, spider):
requests.post(NOTIFICATION_URL, json={
'event': 'ITEM_SCRAPED',
'data': {'spider_name': spider.name, 'item': dict(item)}
})
信号关联
现在启用 NotificationExtension
其实没有任何效果的,我们还需要将这些方法和对应的 Scrapy 信号关联起来,再在 NotificationExtension
类中添加如下类方法:其中 from_crawler
是一个类方法,第一个参数就是 cls
类对象,第二个参数 crawler
代表了 Scrapy 运行过程中全局的 Crawler 对象。在 Crawler 对象里有一个子对象叫作 signals
,通过调用 signals
对象的 connect
方法,我们可以将 Scrapy 运行过程中的某个信号和我们自定义的处理方法关联起来。这样在某个事件发生的时候,被关联的处理方法就会被调用。比如这里,connect
方法第一个参数我们传入 ext.spider_opened
这个对象,而 ext
是由 cls
类对象初始化的,所以 ext.spider_opened
就代表我们在 NotificationExtension
类中定义的 spider_opened
方法。connect
方法的第二个参数我们传入了 signals.spider_opened
这个对象,这就指定了 spider_opened
方法可以被 spider_opened
信号触发。这样在 Spider 开始运行的时候,会产生 signals.spider_opened
信号,NotificationExtension
类中定义的 spider_opened
方法就会被调用了。
from scrapy import signals
@classmethod
def from_crawler(cls, crawler):
ext = cls()
crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)
crawler.signals.connect(ext.spider_scraped, signal=signals.spider_scraped)
return ext
启用配置
和 Downloder Middleware
、Spider Middleware
以及 Item Pipeline
一样, Extension
也是通过 settings.py
中的配置来控制是否被启用,这个配置项就是 EXTENSION
变量。例如:
# 开启CoreStats和TelnetConsole这两个EXTENSION
EXTENSIONS = {
# 启用NotificationExtension定制扩展
'scrapy.extensions.NotificationExtension': 500,
# 启用CoreStats内置扩展
'scrapy.extensions.corestats.CoreStats': 500,
# 启用TelnetConsole内置扩展
'scrapy.extensions.telnet.TelnetConsole': 501
}