关于Python中Scrapy框架signals的用法请教
看了 scrapy 的官方文档,关于 signals 的函数在 from_crawler()中有如下示例代码:
crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened) #代码 1
crawler.signals.connect(ext.spider_closed, signal=signals.spider_closed) #代码 2
对应两个方法定义如下:
def spider_opened(self, spider):
spider.log(“opened spider %s” % spider.name)
def spider_closed(self, spider):
spider.log(“closed spider %s” % spider.name)
恳请大家指点,上面代码中和 signals 的这几个函数和方法到底是完成了什么工作呢? 谢谢!
关于Python中Scrapy框架signals的用法请教
主要是写 extension 用的, 配合几个 signal 当触发器用的, 具体可以看看内置的 extension 代码
Scrapy的signals机制是框架的核心扩展点,让你能在爬虫生命周期中插入自定义逻辑。它基于pydispatch实现,通过信号/槽机制工作。
最常用的几个信号:
engine_started/engine_stopped:引擎启动/停止时触发spider_opened/spider_closed:爬虫打开/关闭时触发item_scraped:item被抓取后触发request_scheduled/response_received:请求调度和响应接收时触发
基本用法示例:
from scrapy import signals
from scrapy.crawler import Crawler
class MySpider(scrapy.Spider):
name = 'example'
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
spider = super().from_crawler(crawler, *args, **kwargs)
# 连接信号处理器
crawler.signals.connect(spider.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(spider.spider_closed, signal=signals.spider_closed)
crawler.signals.connect(spider.item_scraped, signal=signals.item_scraped)
return spider
def spider_opened(self, spider):
print(f"爬虫 {spider.name} 启动了")
def spider_closed(self, spider):
print(f"爬虫 {spider.name} 关闭了")
def item_scraped(self, item, response, spider):
print(f"抓到item: {item}")
def start_requests(self):
yield scrapy.Request('http://example.com', callback=self.parse)
def parse(self, response):
yield {'title': response.css('title::text').get()}
也可以在扩展(Extension)中使用:
from scrapy import signals
from scrapy.exceptions import NotConfigured
class StatsExtension:
def __init__(self, stats):
self.stats = stats
self.item_count = 0
@classmethod
def from_crawler(cls, crawler):
ext = cls(crawler.stats)
crawler.signals.connect(ext.spider_opened, signal=signals.spider_opened)
crawler.signals.connect(ext.item_scraped, signal=signals.item_scraped)
return ext
def spider_opened(self, spider):
self.stats.set_value('start_time', time.time())
def item_scraped(self, item, response, spider):
self.item_count += 1
self.stats.set_value('items_scraped', self.item_count)
关键点:信号处理器接收的参数由具体信号决定,需要查看Scrapy文档确认。比如item_scraped接收(item, response, spider)三个参数,而spider_opened只接收(spider)一个参数。
信号机制让Scrapy的扩展性很强,但别滥用,过度使用会影响性能。
总结:用from_crawler连接信号,根据需求选择合适的信号点。
这里首先注册两个函数 spider_opened, spider_closed。当 spider 启动和关闭的时候会触发。有点类似 wrapper 的概念
比如爬虫结束可以执行一些清理的工作比如发邮件。
非常感谢!!!

