目录
介绍
Scrapy 提供了一个Extension机制,可以让我们添加和扩展一些自定义的功能。利用Extension 我们可以注册一些
处理方法并监听Scrapy 运行过程中的各个信号,做到某个事件发生的时候执行我们自定义的方法
Scrapy 已经内置了一些Extension:
- LogStats:用于记录一些基本的爬取信息,比如爬取的页面数量,提取的item数量等
- CoreStats:用于统计爬取过程中的核心统计信息,如开始爬取时间,爬取结束时间等。
通过如下配置可以开启这两个Extension
# settings.py
EXTENSIONS = {
'scrapy.extensions.corestats.CoreStats': 500,
'scrapy.extensions.telnet.TelnetConsole': 501
}
另外我们也可以实现自定义的Extension,实现过程其实非常简单,主要分为:
- 实现一个Python类,然后实现对应的处理方法,如实现一个spider_opened方法用于处理Spider开始爬取时执行的操作,
可以接收一个spider参数并对其进行操作 - 定义from_crawler类方法,其第一个参数是cls 类对象,第二个参数是crawler。利用crawler的signals对象将Scrapy
的各个信号和已经定义的处理方法关联起来
实战
1.利用 Flask 搭建一个简单的 web 服务器:
from flask import Flask,request,jsonify
from loguru import logger
app = Flask(__name__)
@app.route('/notify', methods=['POST'])
def receive():
post_data = request.get_json()
event = post_data.get('event')
data = post_data.get('data')
logger.debug(f'receive event:{event},data:{data}')
return jsonify(status='success')
if __name__ == '__main__':
app.run(debug=True,host='127.0.0.1',port=5000)
2.新增extensions.py
# @Time: 2022/12/21 10:40
# @Authot: zzc
# @Project: scrapyitempipelinedemo
# @File:extensions.py.py
from scrapy import signals
import requests
notification_url = 'http://127.0.0.1:5000/notify'
class NotificationExtension(object):
def spider_opened(self, spider):
"""
爬取开始时的处理
:param spider:
:return:
"""
requests.post(notification_url, json={
'event':'spider_opened',
'data':{'spider_name':spider.name}
})
def spider_closed(self, spider):
"""
爬取结束时的处理
:param spider:
:return:
"""
requests.post(notification_url,json={
'event':'SPIDER_CLOSED',
'data':{'spider_name':spider.name}
})
def item_scraped(self, item, spider):
"""
爬取到item的处理
:param item:
:param spider:
:return:
"""
requests.post(notification_url,json={
'event':'ITEM_SCRAPED',
'data':{'spider_name':spider.name,'item': dict(item)}
})
@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.item_scraped,signal=signals.item_scraped)
return ext
执行scrapy 后,flask 服务输出:
SPIDER_CLOSED :