1. 事件回调开发
事件回调函数实际上就是一个普通的函数 / 实例方法 / 类方法 / 静态方法,因此回调函数的开发即开发普通的函数,如以下为内置过滤无效状态码等简单的事件函数源码。
from bricks.core import signals
from bricks.core.context import Context
def is_success():
"""
通用的判断响应是否成功
:return:
"""
context: Context = Context.get_context()
response = context.obtain("response")
if not response.ok:
raise signals.Retry
从以上源码我们需要了解的内容是:
- 我们主要操作的对象就是
context
,Context
是爬虫请求过程中的上下文对象,通过该对象,我们可以获取到他的请求/响应等数据 - 只有运行到一定的流程,
Context
的属性才会被赋值,例如,只有在完成请求后,才会有response
属性 - 针对
Context
对象进行相应操作之后,如果要改变运行流程,则需要raise
出signals
信号;比较常用的信号如下signals.Retry
: 重试信号,会中断当前流程并重试请求signals.Success
: 成功信号,会中断当前流程并删除种子signals.Failure
: 失败信号,会中断当前流程并将种子暂时放入failure
队列
- 大体的时间,返回的信号导致的结果是类似的,但是部分环节的事件可能不会处理某些信号,例如初始化的时间和爬虫的事件其实是有细微差别的
2. 事件回调注册
内置接口注册
事件函数一般在 install
接口进行注册,该接口在实例生成的时候会自动调用一次,我们可以看看内置的 air.Spider
的 install
方法,就会默认注册一些事件。
def install(self):
super().install()
self.use(
state.const.BEFORE_REQUEST,
{"func": on_request.Before.fake_ua},
{"func": on_request.Before.set_proxy, "index": math.inf},
)
self.use(
state.const.AFTER_REQUEST,
{"func": on_request.After.show_response},
{"func": on_request.After.conditional_scripts},
{"func": on_request.After.is_success}
)
注册时间使用的是 use
方法
装饰器注册
除了可以使用内置接口注册,还可以使用装饰器注册,方法如下
from bricks import const
from bricks.core import signals, events
@events.on(const.BEFORE_PIPELINE)
def test():
context: Context = Context.get_context()
print(context)
类下的方法同样是支持的
关于
on
函数说明
使用装饰器的方式注册事件 ,如果有 staticmethod
之类的装饰器, 则需要紧贴着你的函数
-
:param binding
: 事件作用对象, 默认为自动判断
如果是类相关的方法(静态方法, 类方法, 实例方法), 则会作用于该类的实例
如果是普通函数(则会作用于全局)
如果传入了对象, 则仅作用于该对象 -
:param form
: 事件类型, 可以传入 const 属性 -
:param index
: 事件排序, 默认会在最后注册执行, 按照代码顺序索引一次递增, 索引越大, 执行速度越靠后 -
:param disposable
: 是否为可弃用事件(仅运行一次)
3. 事件回调取消
有时候如果需要取消事件,可以使用以下方法,但是一般用不上
from bricks import const
from bricks.spider import air
class MySpider(air.Spider):
pass
if __name__ == '__main__':
spider = MySpider()
for i in spider.plugins:
if i.form == const.BEFORE_PIPELINE and i.task.func == spider.is_success:
i.unregister()