组件
Scrapy 组件是任何使用 build_from_crawler() 构建对象的类。
这包括你可以分配给以下设置的类:
ADDONSDNS_RESOLVERDOWNLOAD_HANDLERSDOWNLOADER_CLIENTCONTEXTFACTORYDOWNLOADER_MIDDLEWARESDUPEFILTER_CLASSEXTENSIONSFEED_EXPORTERSFEED_STORAGESITEM_PIPELINESSCHEDULERSCHEDULER_DISK_QUEUESCHEDULER_MEMORY_QUEUESCHEDULER_PRIORITY_QUEUESCHEDULER_START_DISK_QUEUESCHEDULER_START_MEMORY_QUEUESPIDER_MIDDLEWARES
第三方 Scrapy 组件也可能允许你定义额外的 Scrapy 组件,通常通过设置进行配置,以修改它们的行为。
从爬虫初始化
任何 Scrapy 组件都可以选择定义以下类方法:
classmethod from_crawler(cls, crawler: scrapy.crawler.Crawler, *args, **kwargs)
根据 crawler 返回组件的实例。
args 和 kwargs 是某些组件接收的特定于组件的参数。但是,大多数组件不获取任何参数,而是使用设置。
如果组件类定义了此方法,则调用此类方法来创建组件的任何实例。
crawler 对象提供对所有 Scrapy 核心组件的访问,例如 settings 和 signals,允许组件访问它们并将其功能挂接到 Scrapy 中。
设置
组件可以通过设置进行配置。
组件可以从它们可以获取以进行初始化的 Crawler 对象的 settings 属性中读取任何设置。这包括内置设置和自定义设置。
例如:
class MyExtension:
@classmethod
def from_crawler(cls, crawler):
settings = crawler.settings
return cls(settings.getbool("LOG_ENABLED"))
def __init__(self, log_is_enabled=False):
if log_is_enabled:
print("log is enabled!")
组件不需要以编程方式声明其自定义设置。但是,它们应该记录它们,以便用户知道它们的存在以及如何使用它们。
为自定义设置添加组件名称作为前缀是一个好习惯,以避免与其他现有(或未来)组件的自定义设置发生冲突。例如,一个名为 WarcCaching 的扩展可以将其自定义设置前缀为 WARC_CACHING_。
另一个好习惯,主要用于组件优先级字典中的组件,是提供一个名为 <PREFIX>_ENABLED 的布尔设置(例如 WARC_CACHING_ENABLED),以允许在不更改组件优先级字典设置的情况下打开和关闭该组件。你通常可以在初始化期间检查此类设置的值,如果为 False,则引发 NotConfigured。
在为自定义设置选择名称时,最好也查看内置设置的名称,以尝试与它们保持一致。
强制要求
有时,你的组件可能只打算在特定条件下工作。例如,它们可能需要 Scrapy 的最低版本才能按预期工作,或者它们可能需要某些设置具有特定值。
除了在组件文档中描述这些条件之外,如果这些条件在运行时不满足,最好从组件的 __init__ 方法中引发异常。
对于下载器中间件、扩展、项目管道和爬虫中间件,你应该引发 NotConfigured,将问题的描述作为参数传递给异常,以便在日志中打印出来供用户查看。对于其他组件,你可以随意引发任何其他你认为合适的异常;例如,RuntimeError 对于 Scrapy 版本不匹配可能是有意义的,而 ValueError 对于设置值问题可能更好。
如果你的要求是 Scrapy 的最低版本,你可以使用 scrapy.__version__ 来强制执行你的要求。例如:
from packaging.version import parse as parse_version
import scrapy
class MyComponent:
def __init__(self):
if parse_version(scrapy.__version__) < parse_version("2.7"):
raise RuntimeError(
f"{MyComponent.__qualname__} requires Scrapy 2.7 or "
f"later, which allow defining the process_spider_output "
f"method of spider middlewares as an asynchronous "
f"generator."
)
API 参考
以下函数可用于创建组件类的实例:
scrapy.utils.misc.build_from_crawler(objcls: type[T], crawler: Crawler, /, *args: Any, **kwargs: Any) -> T[source]
使用其 from_crawler 或 from_settings 构造函数构造类实例。
版本 2.12 新增。
*args 和 **kwargs 转发到构造函数。
如果生成的实例为 None,则引发 TypeError。
以下函数在实现组件时也很有用,用于报告组件类的导入路径,例如在报告问题时:
scrapy.utils.python.global_object_name(obj: Any) -> str[source]
返回给定对象的完整导入路径。
>>> from scrapy import Request
>>> global_object_name(Request)
'scrapy.http.request.Request'
>>> global_object_name(Request.replace)
'scrapy.http.request.Request.replace'