Scrapy 自定义扩展
介绍
Scrapy 允许我们使用扩展将自定义功能添加到 Scrapy 机制中。Scrapy 提供了丰富的自定义扩展功能,让开发者可以根据自己的需求来扩展其功能。以下是一些常见的自定义扩展功能:
-
中间件扩展:Scrapy 的中间件允许用户在请求被发送到下载器之前或之后对请求和响应进行处理。开发者可以通过编写自定义的中间件来实现一些特定的处理逻辑,比如修改请求头、代理设置、重试逻辑等。
-
管道扩展:Scrapy 的管道用于处理爬取到的数据,在数据存储之前进行处理。用户可以编写自定义的管道来实现数据的处理和存储逻辑,比如数据清洗、去重、存储到数据库等。
-
下载器中间件扩展:下载器中间件与普通中间件类似,不同之处在于下载器中间件只在请求被下载器处理时生效。用户可以编写自定义的下载器中间件来实现一些下载相关的特定处理逻辑,比如设置下载延迟、处理异常等。
-
扩展命令:用户可以编写自定义的命令来扩展 Scrapy 的命令行工具。通过这种方式,用户可以实现一些自定义的管理功能,比如导出数据、生成报告等。
总的来说,Scrapy 的自定义扩展功能使得开发者可以根据自己的需求来定制爬虫的功能,实现更加灵活和定制化的爬虫功能。
加载与关闭扩展类
扩展只是在在 Scrapy 启动时初始化的一些常规类。
你应该使用 Scrapy 设置项来管理扩展。
开启或关闭扩展,可以通过 setting.py
的 EXTENSIONS
选项来控制。该选项会与 scrapy 默认的 EXTENSIONS_BASE
进行合并。
如果扩展依赖于其它扩展,可以通过定义其值,指定加载顺序。
如果某个扩展的值被设置为 None
,代表关闭该扩展。也可以在 settings.py
中将其注释掉或者删除对应的配置。
EXTENSIONS = {
'scrapy.extensions.corestats.CoreStats': 500,
'scrapy.extensions.telnet.TelnetConsole': 500,
# 配置加载扩展类
'myproject.extensions.MyExtension': 500,
}
其中,'myproject.extensions.MyExtension'
是自定义扩展类的路径,500 是加载顺序(数字越小越先加载)。
注意,一些自带的扩展的开启与否并非仅仅依赖于是否扩展类是否加载,例如 HTTP Cache 扩展默认是加载的,但它的功能又依赖于
HTTPCACHE_ENABLED
设置项来控制。
在 Scrapy 中加载和关闭自定义扩展类可以通过在 settings.py 中配置相应的设置来实现。以下是加载和关闭扩展类的方法:
自定义扩展类
扩展就是一个普通的 Python 类。
示例
import logging
from scrapy import signals
from scrapy.exceptions import NotConfigured
logger = logging.getLogger(__name__)
class SpiderOpenCloseLogging(object):
def __init__(self, item_count):
self.item_count = item_count
self.items_scraped = 0
@classmethod
def from_crawler(cls, crawler):
# first check if the extension should be enabled and raise
# NotConfigured otherwise
if not crawler.settings.getbool('MYEXT_ENABLED'):
raise NotConfigured
# get the number of items from settings
item_count = crawler.settings.getint('MYEXT_ITEMCOUNT', 1000)
# instantiate the extension object
ext = cls(item_count)
# connect the extension object to signals
crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed)
crawler.signals.connect(ext.item_scraped, signal=signals.item_scraped)
# return the extension object
return ext
def spider_opened(self, spider):
logger.info("opened spider %s", spider.name)
def spider_closed(self, spider):
logger.info("closed spider %s", spider.name)
def item_scraped(self, item, spider):
self.items_scraped += 1
if self.items_scraped % self.item_count == 0:
logger.info("scraped %d items", self.items_scraped)