python scrapy爬虫扩展加载
2022年5月30日大约 2 分钟约 529 字
加载和激活扩展
扩展在扩展类被实例化时加载和激活。因此,所有扩展的实例化代码必须在类的构造函数(__init__
)中执行。
要使扩展可用,需要把它添加到配置文件的EXTENSIONS
配置项中:
>>> vim ArticleSpider/settings.py
# 扩展加载的顺序并不重要,因为它们并不相互依赖
EXTENSIONS = {
'scrapy.extensions.telnet.TelnetConsole': None,
'ArticleSpider.extensions.test.Test': 500,
}
实现你的扩展
扩展框架提供一个机制,使得你能将自定义功能绑定到scrapy
。
扩展只是一个正常的类,它们在Scrapy
启动时被实例化、初始化。
meddlewares
和pipelines
也是一个扩展,把函数和信号量做了一个绑定,我们只能重写指定的函数。
扩展的主入口是from_srawler
类方法,它接收一个Crawler
类的实例,通过这个对象访问settings,signals,stats
,控制爬虫行为。
通常来说,扩展的函数绑定到signals
并执行它们触发的任务。
最后,如果from_crawler
方法抛出NotConfigured
异常,扩展会被禁用。否则扩展会被开启。
扩展例子
这里我们将实现一个简单的扩展来演示上面描述到的概念。 该扩展会在以下事件时记录一条日志:
- spider被打开
- spider被关闭
- 爬取了特定数量的条目(items)
该扩展通过 MYEXT_ENABLED
配置项开启, items的数量通过 MYEXT_ITEMCOUNT
配置项设置。
以下是扩展的代码:
from scrapy import signals
from scrapy.exceptions import NotConfigured
class SpiderOpenCloseLogging(object):
def __init__(self, item_count):
self.item_count = item_count
self.items_scraped = 0
# 扩展的主入口
@classmethod
def from_crawler(cls, crawler):
# 首先检查是否应该启用扩展,否则引发NotConfigured。
if not crawler.settings.getbool('MYEXT_ENABLED'):
raise NotConfigured
# 从设置中获取Item数
item_count = crawler.settings.getint('MYEXT_ITEMCOUNT', 1000)
# 实例化扩展对象
ext = cls(item_count)
# 将扩展对象连接到信号
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 ext
def spider_opened(self, spider):
spider.log("opened spider %s" % spider.name)
def spider_closed(self, spider):
spider.log("closed spider %s" % spider.name)
def item_scraped(self, item, spider):
self.items_scraped += 1
if self.items_scraped % self.item_count == 0:
spider.log("scraped %d items" % self.items_scraped)