作者:mobiledu2502926997 | 来源:互联网 | 2024-12-16 21:00
Scrapy框架通过信号机制来通知应用程序中的重要事件。开发者可以在自己的爬虫项目中监听这些信号,并执行额外的任务或扩展Scrapy的功能,实现更加个性化的爬虫应用。
Scrapy的信号系统非常灵活,即使信号定义了多个参数,监听这些信号的处理器也无需接受所有参数。信号调度器只会传递处理器声明接收的参数。
下面是一个简单的示例,展示了如何监听信号并执行特定的操作:
from scrapy import signals
from scrapy import Spider
class ExampleSpider(Spider):
name = 'example'
allowed_domains = ['example.com']
start_urls = ['http://example.com/']
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
spider = super(ExampleSpider, cls).from_crawler(crawler, *args, **kwargs)
crawler.signals.connect(spider.spider_closed, signal=signals.spider_closed)
return spider
def spider_closed(self, spider):
spider.logger.info('Spider closed: %s', spider.name)
def parse(self, response):
pass
Scrapy的一些信号支持返回Deferred
对象,这允许你在不阻塞主线程的情况下执行异步代码。如果信号处理器返回了一个Deferred
,Scrapy会等待该Deferred
完成后再继续执行后续操作。
例如,下面的代码展示了如何在抓取到项目后将其发送到服务器:
class AsyncSpider(Spider):
name = 'async_example'
start_urls = ['http://quotes.toscrape.com/page/1/']
@classmethod
def from_crawler(cls, crawler, *args, **kwargs):
spider = super(AsyncSpider, cls).from_crawler(crawler, *args, **kwargs)
crawler.signals.connect(spider.item_scraped, signal=signals.item_scraped)
return spider
def item_scraped(self, item):
d = treq.post('http://example.com/post', json.dumps(item).encode('utf-8'), headers={b'Content-Type': [b'application/json']})
return d
def parse(self, response):
for quote in response.css('div.quote'):
yield {
'text': quote.css('span.text::text').get(),
'author': quote.css('small.author::text').get(),
'tags': quote.css('div.tags a.tag::text').getall(),
}
有关支持Deferred
的信号列表,请参阅内置信号参考。